summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2013-03-05 17:39:48 +0100
committermanuel <manuel@mausz.at>2013-03-05 17:39:48 +0100
commit310a2c101b32a5e71a616027b6a1b788a341bc02 (patch)
treea871e1dda8b1de141ae1400ba666fe3b1de96361
downloadtsclient-310a2c101b32a5e71a616027b6a1b788a341bc02.tar.gz
tsclient-310a2c101b32a5e71a616027b6a1b788a341bc02.tar.bz2
tsclient-310a2c101b32a5e71a616027b6a1b788a341bc02.zip
initial GPLv2 releaseHEADmaster
-rw-r--r--.gitignore3
-rw-r--r--COPYING352
-rw-r--r--Makefile173
-rw-r--r--base64.cpp126
-rw-r--r--base64.h27
-rw-r--r--crc32.cpp166
-rw-r--r--crc32.h108
-rw-r--r--tsapp.cpp617
-rw-r--r--tsapp.h77
-rw-r--r--tschannel.cpp199
-rw-r--r--tschannel.h371
-rw-r--r--tsclient.cfg52
-rw-r--r--tsclient.cpp760
-rw-r--r--tsclient.h489
-rwxr-xr-xtsclient.sh108
-rw-r--r--tscommand.cpp1519
-rw-r--r--tscommand.h524
-rw-r--r--tsconnectionthread.cpp728
-rw-r--r--tsconnectionthread.h176
-rw-r--r--tsheaders.h62
-rw-r--r--tsplayer.cpp200
-rw-r--r--tsplayer.h339
-rw-r--r--tsquerythread.cpp1105
-rw-r--r--tsquerythread.h184
-rw-r--r--tsserver.cpp168
-rw-r--r--tsserver.h243
-rw-r--r--wxbufferex.cpp80
-rw-r--r--wxbufferex.h42
-rw-r--r--wxstreamex.cpp108
-rw-r--r--wxstreamex.h85
30 files changed, 9191 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c23c9ca
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
1tsclient.log
2.libs/*
3.deps/*
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..2cf6990
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,352 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
6
7 Everyone is permitted to copy and distribute verbatim copies
8 of this license document, but changing it is not allowed.
9
10Preamble
11========
12
13The licenses for most software are designed to take away your freedom
14to share and change it. By contrast, the GNU General Public License is
15intended to guarantee your freedom to share and change free
16software--to make sure the software is free for all its users. This
17General Public License applies to most of the Free Software
18Foundation's software and to any other program whose authors commit to
19using it. (Some other Free Software Foundation software is covered by
20the GNU Library General Public License instead.) You can apply it to
21your programs, too.
22
23When we speak of free software, we are referring to freedom, not price.
24Our General Public Licenses are designed to make sure that you have
25the freedom to distribute copies of free software (and charge for this
26service if you wish), that you receive source code or can get it if you
27want it, that you can change the software or use pieces of it in new
28free programs; and that you know you can do these things.
29
30To protect your rights, we need to make restrictions that forbid anyone
31to deny you these rights or to ask you to surrender the rights. These
32restrictions translate to certain responsibilities for you if you
33distribute copies of the software, or if you modify it.
34
35For example, if you distribute copies of such a program, whether gratis
36or for a fee, you must give the recipients all the rights that you
37have. You must make sure that they, too, receive or can get the source
38code. And you must show them these terms so they know their rights.
39
40We protect your rights with two steps: (1) copyright the software, and
41(2) offer you this license which gives you legal permission to copy,
42distribute and/or modify the software.
43
44Also, for each author's protection and ours, we want to make certain
45that everyone understands that there is no warranty for this free
46software. If the software is modified by someone else and passed on, we
47want its recipients to know that what they have is not the original, so
48that any problems introduced by others will not reflect on the original
49authors' reputations.
50
51Finally, any free program is threatened constantly by software patents.
52We wish to avoid the danger that redistributors of a free program will
53individually obtain patent licenses, in effect making the program
54proprietary. To prevent this, we have made it clear that any patent
55must be licensed for everyone's free use or not licensed at all.
56
57The precise terms and conditions for copying, distribution and
58modification follow.
59
60 GNU GENERAL PUBLIC LICENSE
61 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
62 0. This License applies to any program or other work which contains a
63 notice placed by the copyright holder saying it may be distributed
64 under the terms of this General Public License. The "Program",
65 below, refers to any such program or work, and a "work based on
66 the Program" means either the Program or any derivative work under
67 copyright law: that is to say, a work containing the Program or a
68 portion of it, either verbatim or with modifications and/or
69 translated into another language. (Hereinafter, translation is
70 included without limitation in the term "modification".) Each
71 licensee is addressed as "you".
72
73 Activities other than copying, distribution and modification are
74 not covered by this License; they are outside its scope. The act
75 of running the Program is not restricted, and the output from the
76 Program is covered only if its contents constitute a work based on
77 the Program (independent of having been made by running the
78 Program). Whether that is true depends on what the Program does.
79
80 1. You may copy and distribute verbatim copies of the Program's
81 source code as you receive it, in any medium, provided that you
82 conspicuously and appropriately publish on each copy an appropriate
83 copyright notice and disclaimer of warranty; keep intact all the
84 notices that refer to this License and to the absence of any
85 warranty; and give any other recipients of the Program a copy of
86 this License along with the Program.
87
88 You may charge a fee for the physical act of transferring a copy,
89 and you may at your option offer warranty protection in exchange
90 for a fee.
91
92 2. You may modify your copy or copies of the Program or any portion
93 of it, thus forming a work based on the Program, and copy and
94 distribute such modifications or work under the terms of Section 1
95 above, provided that you also meet all of these conditions:
96
97 a. You must cause the modified files to carry prominent notices
98 stating that you changed the files and the date of any change.
99
100 b. You must cause any work that you distribute or publish, that
101 in whole or in part contains or is derived from the Program
102 or any part thereof, to be licensed as a whole at no charge
103 to all third parties under the terms of this License.
104
105 c. If the modified program normally reads commands interactively
106 when run, you must cause it, when started running for such
107 interactive use in the most ordinary way, to print or display
108 an announcement including an appropriate copyright notice and
109 a notice that there is no warranty (or else, saying that you
110 provide a warranty) and that users may redistribute the
111 program under these conditions, and telling the user how to
112 view a copy of this License. (Exception: if the Program
113 itself is interactive but does not normally print such an
114 announcement, your work based on the Program is not required
115 to print an announcement.)
116
117 These requirements apply to the modified work as a whole. If
118 identifiable sections of that work are not derived from the
119 Program, and can be reasonably considered independent and separate
120 works in themselves, then this License, and its terms, do not
121 apply to those sections when you distribute them as separate
122 works. But when you distribute the same sections as part of a
123 whole which is a work based on the Program, the distribution of
124 the whole must be on the terms of this License, whose permissions
125 for other licensees extend to the entire whole, and thus to each
126 and every part regardless of who wrote it.
127
128 Thus, it is not the intent of this section to claim rights or
129 contest your rights to work written entirely by you; rather, the
130 intent is to exercise the right to control the distribution of
131 derivative or collective works based on the Program.
132
133 In addition, mere aggregation of another work not based on the
134 Program with the Program (or with a work based on the Program) on
135 a volume of a storage or distribution medium does not bring the
136 other work under the scope of this License.
137
138 3. You may copy and distribute the Program (or a work based on it,
139 under Section 2) in object code or executable form under the terms
140 of Sections 1 and 2 above provided that you also do one of the
141 following:
142
143 a. Accompany it with the complete corresponding machine-readable
144 source code, which must be distributed under the terms of
145 Sections 1 and 2 above on a medium customarily used for
146 software interchange; or,
147
148 b. Accompany it with a written offer, valid for at least three
149 years, to give any third-party, for a charge no more than your
150 cost of physically performing source distribution, a complete
151 machine-readable copy of the corresponding source code, to be
152 distributed under the terms of Sections 1 and 2 above on a
153 medium customarily used for software interchange; or,
154
155 c. Accompany it with the information you received as to the offer
156 to distribute corresponding source code. (This alternative is
157 allowed only for noncommercial distribution and only if you
158 received the program in object code or executable form with
159 such an offer, in accord with Subsection b above.)
160
161 The source code for a work means the preferred form of the work for
162 making modifications to it. For an executable work, complete
163 source code means all the source code for all modules it contains,
164 plus any associated interface definition files, plus the scripts
165 used to control compilation and installation of the executable.
166 However, as a special exception, the source code distributed need
167 not include anything that is normally distributed (in either
168 source or binary form) with the major components (compiler,
169 kernel, and so on) of the operating system on which the executable
170 runs, unless that component itself accompanies the executable.
171
172 If distribution of executable or object code is made by offering
173 access to copy from a designated place, then offering equivalent
174 access to copy the source code from the same place counts as
175 distribution of the source code, even though third parties are not
176 compelled to copy the source along with the object code.
177
178 4. You may not copy, modify, sublicense, or distribute the Program
179 except as expressly provided under this License. Any attempt
180 otherwise to copy, modify, sublicense or distribute the Program is
181 void, and will automatically terminate your rights under this
182 License. However, parties who have received copies, or rights,
183 from you under this License will not have their licenses
184 terminated so long as such parties remain in full compliance.
185
186 5. You are not required to accept this License, since you have not
187 signed it. However, nothing else grants you permission to modify
188 or distribute the Program or its derivative works. These actions
189 are prohibited by law if you do not accept this License.
190 Therefore, by modifying or distributing the Program (or any work
191 based on the Program), you indicate your acceptance of this
192 License to do so, and all its terms and conditions for copying,
193 distributing or modifying the Program or works based on it.
194
195 6. Each time you redistribute the Program (or any work based on the
196 Program), the recipient automatically receives a license from the
197 original licensor to copy, distribute or modify the Program
198 subject to these terms and conditions. You may not impose any
199 further restrictions on the recipients' exercise of the rights
200 granted herein. You are not responsible for enforcing compliance
201 by third parties to this License.
202
203 7. If, as a consequence of a court judgment or allegation of patent
204 infringement or for any other reason (not limited to patent
205 issues), conditions are imposed on you (whether by court order,
206 agreement or otherwise) that contradict the conditions of this
207 License, they do not excuse you from the conditions of this
208 License. If you cannot distribute so as to satisfy simultaneously
209 your obligations under this License and any other pertinent
210 obligations, then as a consequence you may not distribute the
211 Program at all. For example, if a patent license would not permit
212 royalty-free redistribution of the Program by all those who
213 receive copies directly or indirectly through you, then the only
214 way you could satisfy both it and this License would be to refrain
215 entirely from distribution of the Program.
216
217 If any portion of this section is held invalid or unenforceable
218 under any particular circumstance, the balance of the section is
219 intended to apply and the section as a whole is intended to apply
220 in other circumstances.
221
222 It is not the purpose of this section to induce you to infringe any
223 patents or other property right claims or to contest validity of
224 any such claims; this section has the sole purpose of protecting
225 the integrity of the free software distribution system, which is
226 implemented by public license practices. Many people have made
227 generous contributions to the wide range of software distributed
228 through that system in reliance on consistent application of that
229 system; it is up to the author/donor to decide if he or she is
230 willing to distribute software through any other system and a
231 licensee cannot impose that choice.
232
233 This section is intended to make thoroughly clear what is believed
234 to be a consequence of the rest of this License.
235
236 8. If the distribution and/or use of the Program is restricted in
237 certain countries either by patents or by copyrighted interfaces,
238 the original copyright holder who places the Program under this
239 License may add an explicit geographical distribution limitation
240 excluding those countries, so that distribution is permitted only
241 in or among countries not thus excluded. In such case, this
242 License incorporates the limitation as if written in the body of
243 this License.
244
245 9. The Free Software Foundation may publish revised and/or new
246 versions of the General Public License from time to time. Such
247 new versions will be similar in spirit to the present version, but
248 may differ in detail to address new problems or concerns.
249
250 Each version is given a distinguishing version number. If the
251 Program specifies a version number of this License which applies
252 to it and "any later version", you have the option of following
253 the terms and conditions either of that version or of any later
254 version published by the Free Software Foundation. If the Program
255 does not specify a version number of this License, you may choose
256 any version ever published by the Free Software Foundation.
257
258 10. If you wish to incorporate parts of the Program into other free
259 programs whose distribution conditions are different, write to the
260 author to ask for permission. For software which is copyrighted
261 by the Free Software Foundation, write to the Free Software
262 Foundation; we sometimes make exceptions for this. Our decision
263 will be guided by the two goals of preserving the free status of
264 all derivatives of our free software and of promoting the sharing
265 and reuse of software generally.
266
267 NO WARRANTY
268 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
269 WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
270 LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
271 HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
272 WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
273 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
274 FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
275 QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
276 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
277 SERVICING, REPAIR OR CORRECTION.
278
279 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
280 WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
281 MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
282 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
283 INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
284 INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
285 DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
286 OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
287 OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
288 ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
289
290 END OF TERMS AND CONDITIONS
291How to Apply These Terms to Your New Programs
292=============================================
293
294If you develop a new program, and you want it to be of the greatest
295possible use to the public, the best way to achieve this is to make it
296free software which everyone can redistribute and change under these
297terms.
298
299To do so, attach the following notices to the program. It is safest to
300attach them to the start of each source file to most effectively convey
301the exclusion of warranty; and each file should have at least the
302"copyright" line and a pointer to where the full notice is found.
303
304 ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
305 Copyright (C) YYYY NAME OF AUTHOR
306
307 This program is free software; you can redistribute it and/or modify
308 it under the terms of the GNU General Public License as published by
309 the Free Software Foundation; either version 2 of the License, or
310 (at your option) any later version.
311
312 This program is distributed in the hope that it will be useful,
313 but WITHOUT ANY WARRANTY; without even the implied warranty of
314 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
315 GNU General Public License for more details.
316
317 You should have received a copy of the GNU General Public License
318 along with this program; if not, write to the Free Software
319 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
320
321Also add information on how to contact you by electronic and paper mail.
322
323If the program is interactive, make it output a short notice like this
324when it starts in an interactive mode:
325
326 Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
327 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
328 This is free software, and you are welcome to redistribute it
329 under certain conditions; type `show c' for details.
330
331The hypothetical commands `show w' and `show c' should show the
332appropriate parts of the General Public License. Of course, the
333commands you use may be called something other than `show w' and `show
334c'; they could even be mouse-clicks or menu items--whatever suits your
335program.
336
337You should also get your employer (if you work as a programmer) or your
338school, if any, to sign a "copyright disclaimer" for the program, if
339necessary. Here is a sample; alter the names:
340
341 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
342 `Gnomovision' (which makes passes at compilers) written by James Hacker.
343
344 SIGNATURE OF TY COON, 1 April 1989
345 Ty Coon, President of Vice
346
347This General Public License does not permit incorporating your program
348into proprietary programs. If your program is a subroutine library,
349you may consider it more useful to permit linking proprietary
350applications with the library. If this is what you want to do, use the
351GNU Library General Public License instead of this License.
352
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..592d265
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,173 @@
1########################################################
2# Makefile automatically generated by Code::Blocks IDE #
3########################################################
4
5wxWidgetsPath=$(shell dirname `pwd`)/wxBase-2.8.12
6wxXml2Path=$(shell dirname `pwd`)/wxxml2
7wxXml2Lib=$(shell $(wxWidgetsPath)/wx-config --basename | sed 's/wx\_/wxcode_/')_wxxml2-$(shell $(wxWidgetsPath)/wx-config --release)
8
9### Variables used in this Makefile
10default_CC=$(shell $(wxWidgetsPath)/wx-config --cc)
11default_CPP=$(shell $(wxWidgetsPath)/wx-config --cxx)
12default_LD=$(shell $(wxWidgetsPath)/wx-config --ld | sed 's/-shared//')
13default_LIB=
14
15### Compiler/linker options
16default_GLOBAL_CFLAGS=-g
17default_PROJECT_CFLAGS=$(shell $(wxWidgetsPath)/wx-config --cppflags)
18default_PROJECT_CFLAGS+= -Wall -Wextra -pipe -fno-pcc-struct-return -fno-rtti -fno-exceptions -DwxUSE_UNICODE=1 -D_X86_
19default_GLOBAL_LDFLAGS=
20default_PROJECT_LDFLAGS=
21default_GLOBAL_INCS= -I$(wxXml2Path)/include -I/usr/include -I/usr/include/libxml2
22default_PROJECT_INCS=
23default_GLOBAL_LIBDIRS=
24default_PROJECT_LIBDIRS=
25default_GLOBAL_LIBS=
26default_PROJECT_LIBS=$(shell $(wxWidgetsPath)/wx-config --libs) -L$(wxXml2Path)/lib -Wl,-rpath,$(wxXml2Path)/lib -l:lib$(wxXml2Lib).so.0 -lxml2
27
28### Targets compiler flags
29default_CFLAGS= $(default_PROJECT_CFLAGS) $(default_GLOBAL_CFLAGS)
30
31### Targets linker flags
32default_LDFLAGS= $(default_PROJECT_LDFLAGS) $(default_GLOBAL_LDFLAGS)
33
34### Targets include directories
35default_INCS= $(default_PROJECT_INCS) $(default_GLOBAL_INCS)
36
37### Targets library directories
38default_LIBDIRS= $(default_PROJECT_LIBDIRS) $(default_GLOBAL_LIBDIRS)
39
40### Targets libraries
41default_LIBS= $(default_PROJECT_LIBS) $(default_GLOBAL_LIBS)
42
43###############################################################################
44# You shouldn't need to modify anything beyond this point #
45###############################################################################
46
47### Resources used in this Makefile
48default_RESOURCE=
49
50### Objects used in this Makefile
51default_OBJS=.objs/crc32.o .objs/base64.o .objs/tsapp.o .objs/tschannel.o \
52 .objs/tsclient.o .objs/tscommand.o .objs/tsconnectionthread.o \
53 .objs/tsquerythread.o .objs/tsplayer.o .objs/tsserver.o \
54 .objs/wxstreamex.o .objs/wxbufferex.o
55default_LINKOBJS=$(default_OBJS)
56default_DEPS=.deps/crc32.d .deps/base64.d .deps/tsapp.d .deps/tschannel.d \
57 .deps/tsclient.d .deps/tscommand.d .deps/tsconnectionthread.d \
58 .deps/tsquerythread.d .deps/tsplayer.d .deps/tsserver.d \
59 .deps/wxstreamex.d .deps/wxbufferex.d
60
61### The targets of this project
62default_BIN=tsclient
63
64.PHONY: all all-before all-custom all-after clean clean-custom distclean distclean-custom depend_default default-before default-after
65
66all: all-before default all-after
67
68
69dist:
70 @zip tsclient.zip Makefile crc32.cpp crc32.h base64.c base64.h tsapp.cpp \
71 tsapp.h tschannel.cpp tschannel.h tsclient.cpp tsclient.h tscommand.cpp \
72 tscommand.h tsconnectionthread.cpp tsconnectionthread.h tsplayer.cpp \
73 tsplayer.h tsserver.cpp tsserver.h wxstreamex.cpp wxstreamex.h
74
75clean_default:
76 $(RM) $(default_BIN) $(default_OBJS) $(default_RESOURCE)
77
78distclean_default:
79 $(RM) $(default_BIN) $(default_OBJS) $(default_DEPS) $(default_RESOURCE)
80
81clean: clean_default
82
83distclean: distclean_default
84
85depend_default_DIRS:
86 -@if [ ! -e .deps ]; then mkdir .deps; fi
87
88depend_default: depend_default_DIRS $(default_DEPS)
89
90depend: depend_default
91
92default_DIRS:
93 -@if [ ! -e .objs ]; then mkdir .objs; fi
94
95default: depend_default default_DIRS default-before $(default_BIN) default-after
96
97$(default_BIN): $(default_LINKOBJS) $(default_RESOURCE)
98 $(default_LD) $(default_LIBDIRS) $(default_BIN) $(default_LINKOBJS) $(default_RESOURCE) $(default_LDFLAGS) $(default_LIBS)
99
100tsheaders=tschannel.h tsclient.h tscommand.h tsconnectionthread.h tsheaders.h \
101 tsplayer.h tsserver.h
102
103.deps/crc32.d: crc32.cpp crc32.h
104 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/crc32.d -MT .objs/crc32.o $(default_INCS) crc32.cpp
105
106.objs/crc32.o: .deps/crc32.d
107 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c crc32.cpp -o .objs/crc32.o
108
109.deps/base64.d: base64.cpp base64.h
110 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/base64.d -MT .objs/base64.o $(default_INCS) base64.cpp
111
112.objs/base64.o: .deps/base64.d
113 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c base64.cpp -o .objs/base64.o
114
115.deps/tsapp.d: tsapp.cpp tsapp.h $(tsheaders) tsquerythread.h
116 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tsapp.d -MT .objs/tsapp.o $(default_INCS) tsapp.cpp
117
118.objs/tsapp.o: .deps/tsapp.d
119 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tsapp.cpp -o .objs/tsapp.o
120
121.deps/tschannel.d: tschannel.cpp $(tsheaders)
122 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tschannel.d -MT .objs/tschannel.o $(default_INCS) tschannel.cpp
123
124.objs/tschannel.o: .deps/tschannel.d
125 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tschannel.cpp -o .objs/tschannel.o
126
127.deps/tsclient.d: tsclient.cpp $(tsheaders) tsserver.h
128 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tsclient.d -MT .objs/tsclient.o $(default_INCS) tsclient.cpp
129
130.objs/tsclient.o: .deps/tsclient.d
131 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tsclient.cpp -o .objs/tsclient.o
132
133.deps/tscommand.d: tscommand.cpp $(tsheaders) crc32.h wxbufferex.h wxstreamex.h
134 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tscommand.d -MT .objs/tscommand.o $(default_INCS) tscommand.cpp
135
136.objs/tscommand.o: .deps/tscommand.d
137 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tscommand.cpp -o .objs/tscommand.o
138
139.deps/tsconnectionthread.d: tsconnectionthread.cpp $(tsheaders) wxbufferex.h
140 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tsconnectionthread.d -MT .objs/tsconnectionthread.o $(default_INCS) tsconnectionthread.cpp
141
142.objs/tsconnectionthread.o: .deps/tsconnectionthread.d
143 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tsconnectionthread.cpp -o .objs/tsconnectionthread.o
144
145.deps/tsquerythread.d: tsquerythread.cpp tsquerythread.h $(tsheaders) base64.h wxbufferex.h
146 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tsquerythread.d -MT .objs/tsquerythread.o $(default_INCS) tsquerythread.cpp
147
148.objs/tsquerythread.o: .deps/tsquerythread.d
149 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tsquerythread.cpp -o .objs/tsquerythread.o
150
151.deps/tsplayer.d: tsplayer.cpp $(tsheaders)
152 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tsplayer.d -MT .objs/tsplayer.o $(default_INCS) tsplayer.cpp
153
154.objs/tsplayer.o: .deps/tsplayer.d
155 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tsplayer.cpp -o .objs/tsplayer.o
156
157.deps/tsserver.d: tsserver.cpp tsserver.h
158 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/tsserver.d -MT .objs/tsserver.o $(default_INCS) tsserver.cpp
159
160.objs/tsserver.o: .deps/tsserver.d
161 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c tsserver.cpp -o .objs/tsserver.o
162
163.deps/wxstreamex.d: wxstreamex.cpp wxbufferex.h
164 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/wxstreamex.d -MT .objs/wxstreamex.o $(default_INCS) wxstreamex.cpp
165
166.objs/wxstreamex.o: .deps/wxstreamex.d
167 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c wxstreamex.cpp -o .objs/wxstreamex.o
168
169.deps/wxbufferex.d: wxbufferex.cpp wxstreamex.h
170 $(default_CPP) -MM $(default_CFLAGS) -MF .deps/wxbufferex.d -MT .objs/wxbufferex.o $(default_INCS) wxbufferex.cpp
171
172.objs/wxbufferex.o: .deps/wxbufferex.d
173 $(default_CPP) $(default_CFLAGS) $(default_INCS) -c wxbufferex.cpp -o .objs/wxbufferex.o
diff --git a/base64.cpp b/base64.cpp
new file mode 100644
index 0000000..38837fe
--- /dev/null
+++ b/base64.cpp
@@ -0,0 +1,126 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19//Header
20#include "base64.h"
21
22//Libraries
23#include <ctype.h>
24
25static const wxString base64_chars =
26 _T("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
27 _T("abcdefghijklmnopqrstuvwxyz")
28 _T("0123456789+/");
29
30
31static inline bool is_base64(unsigned char c)
32{
33 return (isalnum(c) || (c == '+') || (c == '/'));
34}
35
36wxString Base64Encode(char const* bytes_to_encode, unsigned int in_len)
37{
38 wxString ret;
39 int i = 0;
40 int j = 0;
41 unsigned char char_array_3[3];
42 unsigned char char_array_4[4];
43
44 while (in_len--)
45 {
46 char_array_3[i++] = *(bytes_to_encode++);
47 if (i == 3) {
48 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
49 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
50 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
51 char_array_4[3] = char_array_3[2] & 0x3f;
52
53 for(i = 0; i < 4; i++)
54 ret += base64_chars[char_array_4[i]];
55 i = 0;
56 }
57 }
58
59 if (i)
60 {
61 for(j = i; j < 3; j++)
62 char_array_3[j] = '\0';
63
64 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
65 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
66 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
67 char_array_4[3] = char_array_3[2] & 0x3f;
68
69 for (j = 0; j < i + 1; j++)
70 ret += base64_chars[char_array_4[j]];
71
72 while(i++ < 3)
73 ret += '=';
74 }
75
76 return ret;
77
78}
79
80wxString Base64Decode(wxString const& encoded_string)
81{
82 int in_len = encoded_string.size();
83 int i = 0;
84 int j = 0;
85 int in_ = 0;
86 unsigned char char_array_4[4], char_array_3[3];
87 wxString ret;
88
89 while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))
90 {
91 char_array_4[i++] = encoded_string[in_];
92 in_++;
93 if (i ==4)
94 {
95 for (i = 0; i < 4; i++)
96 char_array_4[i] = base64_chars.find(char_array_4[i]);
97
98 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
99 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
100 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
101
102 for (i = 0; i < 3; i++)
103 ret += char_array_3[i];
104 i = 0;
105 }
106 }
107
108 if (i)
109 {
110 for (j = i; j < 4; j++)
111 char_array_4[j] = 0;
112
113 for (j = 0; j < 4; j++)
114 char_array_4[j] = base64_chars.find(char_array_4[j]);
115
116 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
117 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
118 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
119
120 for (j = 0; j < i - 1; j++)
121 ret += char_array_3[j];
122 }
123
124 return ret;
125}
126
diff --git a/base64.h b/base64.h
new file mode 100644
index 0000000..15a34a0
--- /dev/null
+++ b/base64.h
@@ -0,0 +1,27 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef BASE64_H
20#define BASE64_H
21
22#include <wx/string.h>
23
24wxString Base64Encode(char const* , unsigned int len);
25wxString Base64Decode(wxString const& s);
26
27#endif
diff --git a/crc32.cpp b/crc32.cpp
new file mode 100644
index 0000000..fa4423c
--- /dev/null
+++ b/crc32.cpp
@@ -0,0 +1,166 @@
1/*
2 * CRC32
3 * Written by Julien Couot.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/**
21 * \file crc32.cpp
22 * Compute crc32.
23 */
24
25//---------------------------------------------------------------------------
26// For compilers that support precompilation, includes "wx.h".
27#include <wx/wxprec.h>
28
29#ifdef __BORLANDC__
30#pragma hdrstop
31#endif
32
33#ifndef WX_PRECOMP
34// Include your minimal set of headers here, or wx.h
35#include <wx/wx.h>
36#endif
37
38#include "crc32.h"
39
40//---------------------------------------------------------------------------
41
42// Table used to compute the CRC32 value.
43const wxUint32 CRC32::crc_table[256] =
44{
45 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
46 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
47 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
48 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
49 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
50 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
51 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
52 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
53 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
54 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
55 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
56 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
57 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
58 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
59 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
60 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
61 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
62 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
63 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
64 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
65 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
66 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
67 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
68 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
69 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
70 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
71 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
72 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
73 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
74 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
75 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
76 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
77 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
78 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
79 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
80 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
81 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
82 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
83 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
84 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
85 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
86 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
87 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
88 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
89 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
90 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
91 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
92 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
93 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
94 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
95 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
96 0x2d02ef8d
97};
98//---------------------------------------------------------------------------
99
100/*
101 * Default constructor.
102 */
103CRC32::CRC32()
104{
105 reset();
106}
107
108//---------------------------------------------------------------------------
109
110/*
111 * Resets the CRC32 to initial value.
112 */
113void CRC32::reset()
114{
115 crc32 = 0xffffffff;
116}
117
118//---------------------------------------------------------------------------
119
120/*
121 * Returns the CRC32 value.
122 */
123wxUint32 CRC32::getUint32Value() const
124{
125 return crc32 ^ 0xffffffff;
126}
127
128//---------------------------------------------------------------------------
129
130/*
131 * Returns the checksum value in a string.
132 *
133 * @param hexInUpperCase If <CODE>true</CODE> the hexadecimal letters will
134 * be in uppercase.
135 * @return The current checksum value.
136 */
137wxString CRC32::getValue(const bool hexInUpperCase) const
138{
139 wxString h;
140 if(hexInUpperCase)
141 h = wxString(_T("%08X"));
142 else
143 h = wxString(_T("%08x"));
144
145 return wxString::Format(h, getUint32Value());
146}
147
148//---------------------------------------------------------------------------
149
150/*
151 * Updates the CRC32 with specified array of bytes.
152 */
153void CRC32::update(const wxByte *buf, unsigned int len)
154{
155 if(buf == NULL || len == 0)
156 return;
157
158 do
159 {
160 crc32 = crc_table[(crc32 ^ (*buf++)) & 0xff] ^ (crc32 >> 8);
161 }
162 while(--len);
163}
164
165//---------------------------------------------------------------------------
166
diff --git a/crc32.h b/crc32.h
new file mode 100644
index 0000000..6114d96
--- /dev/null
+++ b/crc32.h
@@ -0,0 +1,108 @@
1/*
2 * CRC32
3 * Written by Julien Couot.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/**
21 * \file crc32.h
22 * Compute crc32.
23 */
24
25#ifndef CRC32_H
26#define CRC32_H
27
28//---------------------------------------------------------------------------
29// For compilers that support precompilation, includes "wx.h".
30#include <wx/wxprec.h>
31
32#ifdef __BORLANDC__
33#pragma hdrstop
34#endif
35
36#ifndef WX_PRECOMP
37// Include your minimal set of headers here, or wx.h
38#include <wx/wx.h>
39#endif
40
41//---------------------------------------------------------------------------
42
43
44/**
45 * Computes the CRC-32 from a byte stream.
46 *
47 * This class is writen with the code found in
48 * <A HREF="http://www.fodder.org/cksfv/">cksfv</A> and
49 * <A HREF="http://www.gzip.org/zlib/">zlib</A> code.
50 *
51 * Using this class in very simple:<BR>
52 * Use the @link update(const wxByte* buf, unsigned int len) update @endlink
53 * method to provide to the class the bytes for computing the checksum.
54 *
55 * The CRC-32 checksum value can be gotten by the @link getValue(const bool) const
56 * getValue @endlink method which puts the CRC32 checksum value in a
57 * unsigned 32 bits integer.
58 *
59 * The CRC32 checksum computing can be reseted by the @link reset() reset
60 * @endlink method.
61 */
62class CRC32
63{
64 protected:
65 /// Table used to compute the CRC32 value.
66 static const wxUint32 crc_table[256];
67
68 /// The current CRC32 value.
69 wxUint32 crc32;
70
71 public:
72 /**
73 * Default constructor.
74 */
75 CRC32();
76
77 /**
78 * Resets the CRC32 to initial value.
79 */
80 void reset();
81
82 /**
83 * Returns the CRC32 value.
84 *
85 * @return The current checksum value.
86 */
87 wxUint32 getUint32Value() const;
88
89 /**
90 * Returns the CRC32 value in a string.
91 *
92 * @param hexInUpperCase If <CODE>true</CODE> the hexadecimal letters will
93 * be in uppercase.
94 * @return The current CRC32 value.
95 */
96 wxString getValue(const bool hexInUpperCase = false) const;
97
98 /**
99 * Updates the CRC32 with specified array of bytes.
100 *
101 * @param buf The byte array to update the CRC32 with.
102 * @param len The number of bytes to use for the update.
103 */
104 void update(const wxByte *buf, unsigned int len);
105};
106//---------------------------------------------------------------------------
107
108#endif
diff --git a/tsapp.cpp b/tsapp.cpp
new file mode 100644
index 0000000..3818b4c
--- /dev/null
+++ b/tsapp.cpp
@@ -0,0 +1,617 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19//Header
20#include "tsapp.h"
21#include "tsheaders.h"
22
23//Libraries
24#include <wx/wx.h>
25#include <wx/cmdline.h>
26#include <wx/wfstream.h>
27#include <wx/txtstrm.h>
28#include <wx/sstream.h>
29#if defined(__UNIX__)
30# include <sys/ioctl.h>
31#endif
32
33//------------------------------------------------------------------------------
34// OnInit
35bool TSApp::OnInit()
36{
37 m_pLog = NULL;
38 m_pLogFile = NULL;
39 m_pConfig = NULL;
40 m_pClient = NULL;
41 m_pQuery = NULL;
42 m_ConfigFileName = CONFIG_FILE_NAME;
43
44 if (!wxAppConsole::OnInit())
45 return false;
46
47 return true;
48}
49
50//------------------------------------------------------------------------------
51// OnExit
52int TSApp::OnExit()
53{
54 //cleanup
55 wxAppConsole::OnExit();
56
57 if(m_pLogFile != NULL && m_pLogFile->IsOpened())
58 m_pLogFile->Close();
59
60 if(m_pLogFile != NULL)
61 delete m_pLogFile;
62 m_pLogFile = NULL;
63
64 if(m_pQuery != NULL)
65 delete m_pQuery;
66 m_pQuery = NULL;
67
68 if(m_pClient != NULL)
69 delete m_pClient;
70 m_pClient = NULL;
71
72 if(m_pConfig != NULL)
73 delete m_pConfig;
74 m_pConfig = NULL;
75
76 if(m_pLog != NULL)
77 delete m_pLog;
78 m_pLog = NULL;
79
80 if(m_pQuery != NULL)
81 delete m_pQuery;
82 m_pQuery = NULL;
83
84 return true;
85}
86
87//------------------------------------------------------------------------------
88// Program entry point, replacment for main()
89int TSApp::OnRun()
90{
91 wxStringOutputStream out;
92
93 //UNIX stuff
94 #if defined(__UNIX__)
95 if(!m_Foreground && !m_Interactive)
96 {
97 int pid = fork();
98 if(pid < 0)
99 {
100 wxLogError(_T("can't fork"));
101 return EXIT_FAILURE;
102 }
103 else if(pid != 0)
104 return EXIT_SUCCESS;
105
106 //detach from tty
107 if (!m_Logtostderr)
108 {
109 //close existing file descriptors
110 for (int fd = getdtablesize() - 1; fd >= 0; fd--)
111 close(fd);
112
113 //open stdin on /dev/null
114 open("/dev/null", O_RDWR);
115 }
116 }
117 #endif
118
119 //welcome message
120 wxPrintf(_T("TeamSpeak Client v0.3 (c)2006-2013 Clan-Server.at\n"));
121
122 m_pLog->SetTimestamp(_T("[%x %X]"));
123 wxLog::SetActiveTarget(m_pLog);
124 wxSocketBase::Initialize();
125
126 m_pClient = new TSClient;
127 m_pQuery = new TSQueryThread(m_pClient);
128
129 //load config
130 if(!LoadConfig(m_ConfigFileName))
131 {
132 wxLogError(_T("can't open config file %s"), m_ConfigFileName.c_str());
133 return EXIT_FAILURE;
134 }
135
136 //open logfile
137 if(m_pLogFileStr.Length() > 0 && !m_Logtostderr && (m_pLogFile == NULL || !m_pLogFile->IsOpened()))
138 {
139 m_pLogFile = new wxFFile(m_pLogFileStr.c_str(), _T("a+"));
140 if(!m_pLogFile->IsOpened())
141 {
142 wxLogError(_T("can't open logfile '%s'."), m_pLogFileStr.c_str());
143 return false;
144 }
145 if (m_pLog != NULL)
146 delete m_pLog;
147 m_pLog = new wxLogStderr((FILE *)m_pLogFile->fp());
148 }
149
150 //start query thread
151 m_pQuery->Start();
152
153 //check for interactive mode
154 if(m_Interactive)
155 Interactive();
156 else
157 {
158 while(m_pClient->IsReconnectActive())
159 {
160 if(!m_pClient->IsConnected())
161 {
162 m_pClient->Disconnect();
163 //some status info
164 wxLogMessage(_T("TSServer: connecting to %s:%d..."),
165 m_pClient->GetServer()->GetServerAddress().c_str(),
166 m_pClient->GetServer()->GetPort());
167
168 //connect
169 if(!m_pClient->Connect())
170 {
171 wxLogError(_T("%s, error connecting."), m_pClient->GetLastError().c_str());
172 wxSleep(RECONNECT_TIMEOUT);
173 }
174 else
175 wxLogMessage(_T("TSServer: connection established..."));
176 }
177 wxSleep(1);
178 }
179 }
180
181 wxLogMessage(_T("TSServer: disconnecting..."));
182 m_pClient->Disconnect();
183 m_pQuery->Stop();
184 wxSocketBase::Shutdown();
185 wxLogMessage(_T("TSServer: shutting down successful."));
186 wxLog::SetActiveTarget(NULL);
187 return EXIT_SUCCESS;
188}
189
190//------------------------------------------------------------------------------
191// Load config
192bool TSApp::LoadConfig(wxString const &filename)
193{
194 wxString str;
195 if(!wxFileExists(filename))
196 return false;
197
198 m_pConfig = new wxFileConfig(_T("TSDaemon"),
199 wxEmptyString,
200 filename,
201 filename,
202 wxCONFIG_USE_RELATIVE_PATH);
203
204 m_pConfig->Read(_T("LogFile"), &str, _T(""));
205 if(m_pLogFileStr.Length() <= 0)
206 m_pLogFileStr = str;
207
208 //TSClient
209 m_pConfig->Read(_T("TSPlatform"), &str, _T("Windows XP"));
210 m_pClient->SetPlatform(str);
211
212 m_pConfig->Read(_T("TSVersionNumber"), &str, _T("2.0.32.60"));
213 m_pClient->SetVersionNumber(str);
214
215 TSPlayer *pTSP = new TSPlayer;
216 m_pConfig->Read(_T("TSLoginName"), &str, _T(""));
217 pTSP->SetLoginName(str);
218 m_pConfig->Read(_T("TSLoginPassword"), &str, _T(""));
219 pTSP->SetLoginPassword(str);
220 m_pConfig->Read(_T("TSNickname"), &str, _T(""));
221 pTSP->SetNickname(str);
222 //now the TSClient takes care of the pointer.
223 m_pClient->SetPlayer(pTSP);
224
225 TSServer *pTSS = new TSServer;
226 m_pConfig->Read(_T("TSServerAddress"), &str, _T(""));
227 pTSS->SetServerAddress(str);
228 long l;
229 m_pConfig->Read(_T("TSPort"), &l, 0);
230 if(!pTSS->SetPort(l))
231 wxLogError(_T("port, %s"), pTSS->GetLastError().c_str());
232
233 //now the TSClient takes care of the pointer.
234 m_pClient->SetServer(pTSS);
235
236 m_pConfig->Read(_T("ServerAddress"), &str, _T(""));
237 m_pQuery->SetServerAddress(str);
238
239 m_pConfig->Read(_T("AllowedAddresses"), &str, _T(""));
240 m_pQuery->SetAllowedAddresses(str);
241
242 m_pConfig->Read(_T("Port"), &l, 0);
243 if(!m_pQuery->SetPort(l))
244 wxLogError(_T("port, %s"), m_pQuery->GetLastError().c_str());
245
246 m_pConfig->Read(_T("Password"), &str, _T(""));
247 if(!m_pQuery->SetPassword(str))
248 wxLogError(_T("password, %s"), m_pQuery->GetLastError().c_str());
249
250 return true;
251}
252
253//------------------------------------------------------------------------------
254// Set parser line description
255void TSApp::OnInitCmdLine(wxCmdLineParser &parser)
256{
257 //declare CmdLineParser
258 static const wxCmdLineEntryDesc cmdLineDesc[] =
259 {
260 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
261 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
262 { wxCMD_LINE_SWITCH, _T("i"), _T("interactive"), _T("interactive mode"),
263 wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
264 { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") ,
265 wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL},
266 { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") ,
267 wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL},
268 #if defined(__UNIX__)
269 { wxCMD_LINE_SWITCH, _T("f"), _T("foreground"), _T("run in foreground mode"),
270 wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL},
271 #endif
272 { wxCMD_LINE_SWITCH, _T("g"), _T("logtostderr"), _T("log everything to stderr"),
273 wxCMD_LINE_VAL_NONE,wxCMD_LINE_PARAM_OPTIONAL},
274 { wxCMD_LINE_OPTION, _T("c"), _T("config"), _T("path to config file"),
275 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
276 { wxCMD_LINE_OPTION, _T("l"), _T("logfile"), _T("path to log file"),
277 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
278 { wxCMD_LINE_NONE, NULL, NULL, NULL, (wxCmdLineParamType)0, 0 } //ends list
279 };
280 parser.SetDesc(cmdLineDesc);
281
282 //no long options on windows
283 #ifdef __WINDOWS__
284 parser.DisableLongOptions();
285 #endif
286}
287
288//------------------------------------------------------------------------------
289// Process command line options
290bool TSApp::OnCmdLineParsed(wxCmdLineParser &parser)
291{
292 m_Interactive = false;
293 m_Foreground = false;
294 m_Logtostderr = false;
295
296 /* Create and hook logtarget in */
297 if (m_pLog != NULL)
298 delete m_pLog;
299 m_pLog = new wxLogStderr(stdout);
300
301 #if defined __UNIX__
302 if(parser.Found(_T("f")))
303 m_Foreground = true;
304 else
305 m_Foreground = false;
306 #endif
307
308 if(parser.Found(_T("i")))
309 {
310 m_Interactive = true;
311 #if defined __UNIX__
312 m_Foreground = true;
313 #endif
314 }
315
316 if(parser.Found(_T("g")))
317 {
318 if (m_pLog != NULL)
319 delete m_pLog;
320 m_pLog = new wxLogStderr(stderr);
321 m_Logtostderr = true;
322 }
323
324 if(parser.Found(_T("q")))
325 m_pLog->SetLogLevel(wxLOG_FatalError);
326
327 if(parser.Found(_T("v")))
328 m_pLog->SetVerbose(true);
329
330 wxString str;
331 if(parser.Found(_T("c"), &str))
332 m_ConfigFileName = str;
333
334 if(parser.Found(_T("l"), &str) && m_pLogFileStr.Length() <= 0)
335 m_pLogFileStr = str;
336
337 return true;
338}
339
340//------------------------------------------------------------------------------
341// Process help (-h) command line option
342bool TSApp::OnCmdLineHelp(wxCmdLineParser &parser)
343{
344 parser.Usage();
345 return false;
346}
347
348//------------------------------------------------------------------------------
349// Process command line options errors
350bool TSApp::OnCmdLineError(wxCmdLineParser &parser)
351{
352 parser.Usage();
353 return false;
354}
355
356//------------------------------------------------------------------------------
357// ReadString
358wxString TSApp::ReadString(wxString const &str)
359{
360 wxChar cstr[80];
361 wxString s;
362 wxPrintf(_T("%s: "), str.c_str());
363 wxScanf(_T("%s"), cstr);
364 s = cstr;
365 return s;
366}
367
368//------------------------------------------------------------------------------
369// Interactive mode
370bool TSApp::Interactive()
371{
372 wxStringOutputStream out;
373 wxChar cstr[80];
374 wxString str;
375
376 wxPrintf(_T("Type \"help\" for all commands.\n"));
377 do
378 {
379 wxPrintf(_T(">"));
380 wxScanf(_T("%s"), cstr);
381 str = cstr;
382 //--------------------------------------------------------
383 if(str == _T("cl"))
384 {
385 wxPrintf(wxString(_T("-"), 40).c_str());
386 wxPrintf(_T("\ndumping channels...\n"));
387 wxPrintf(_T(" total: %d\n"), m_pClient->GetChannels()->GetCount());
388
389 for(size_t i = 0; i < m_pClient->GetChannels()->GetCount(); i++)
390 wxPrintf(_T("%.3d %s\n"), i, m_pClient->GetChannels()->Item(i)->GetName().c_str());
391 wxPrintf(_T(" total: %d channels\n"), m_pClient->GetChannels()->GetCount());
392 }
393 //--------------------------------------------------------
394 else if(str == _T("pl"))
395 {
396 wxPrintf(wxString(_T("-"), 40).c_str());
397 wxPrintf(_T("\ndumping players...\n"));
398 wxPrintf(_T(" total: %d\n"), m_pClient->GetPlayers()->GetCount());
399
400 for(size_t i = 0; i < m_pClient->GetPlayers()->GetCount(); i++)
401 wxPrintf(_T("%.3d %s\n"), i, m_pClient->GetPlayers()->Item(i)->GetNickname().c_str());
402 wxPrintf(_T(" total: %d players\n"), m_pClient->GetPlayers()->GetCount());
403 }
404 //--------------------------------------------------------
405 else if(str == _T("pcl"))
406 {
407 wxPrintf(wxString(_T("-"), 40).c_str());
408 wxPrintf(_T("\ndumping players with channels...\n"));
409 wxPrintf(_T(" total: %d\n"), m_pClient->GetPlayers()->GetCount());
410
411 for(size_t i = 0; i < m_pClient->GetPlayers()->GetCount(); i++)
412 {
413 wxUint32 chid = m_pClient->GetPlayers()->Item(i)->GetChannelId();
414 wxString nick = m_pClient->GetPlayers()->Item(i)->GetNickname();
415 wxString chl = _T("error");
416
417 for(size_t j = 0; j < m_pClient->GetChannels()->GetCount(); j++)
418 {
419 if(m_pClient->GetChannels()->Item(j)->GetId() == chid)
420 {
421 chl = m_pClient->GetChannels()->Item(j)->GetName();
422 break;
423 }
424 }
425 wxPrintf(_T("%.3d %s \t\t %s\n"), i, nick.c_str(), chl.c_str());
426 }
427 wxPrintf(_T(" total: %d players\n"), m_pClient->GetPlayers()->GetCount());
428 }
429 //--------------------------------------------------------
430 else if(str == _T("cc"))
431 {
432 TSChannel ch;
433 wxString str;
434
435 wxPrintf(_T("create channel...\n"));
436 ch.SetName(ReadString(_T("Name")));
437 ch.SetTopic(ReadString(_T("Topic")));
438 ch.SetDescription(ReadString(_T("Description")));
439 str = ReadString(_T("Password ('.' no pass)"));
440 if(str != _T("."))
441 ch.SetPassword(str);
442 ch.SetFlags(ReadString(_T("Flags")));
443
444 if(m_pClient->CreateChannel(&ch))
445 wxPrintf(_T("channel created\n"));
446 else
447 wxLogError(_T("%s"),m_pClient->GetLastError().c_str());
448 }
449 //--------------------------------------------------------
450 else if(str == _T("mc"))
451 {
452 TSChannel ch;
453 TSChannel *pChl;
454 wxString s,str;
455 wxPrintf(_T("modify channel...\n"));
456
457 s = ReadString(_T("Name"));
458 pChl = m_pClient->FindChannel(s);
459 if(pChl == NULL)
460 {
461 wxPrintf(_T("channel not found\n"));
462 }
463 else
464 {
465 wxPrintf(_T("edit channel\n"));
466 ch.SetId(pChl->GetId());
467 ch.SetName(ReadString(_T("Name")));
468 ch.SetTopic(ReadString(_T("Topic")));
469 ch.SetDescription(ReadString(_T("Description")));
470 str = ReadString(_T("Password ('.' no pass)"));
471 if(str != _T("."))
472 ch.SetPassword(str);
473 ch.SetFlags(ReadString(_T("Flags")));
474
475 if(m_pClient->ModifyChannel(&ch))
476 wxPrintf(_T("channel modified\n"));
477 else
478 wxLogError(_T("%s"),m_pClient->GetLastError().c_str());
479 }
480 }
481 //--------------------------------------------------------
482 else if(str == _T("dc"))
483 {
484 wxString s;
485 TSChannel *pChl;
486
487 wxPrintf(_T("delete channel...\n"));
488 s = ReadString(_T("Name"));
489
490 pChl = m_pClient->FindChannel(s);
491 if(pChl == NULL)
492 {
493 wxPrintf(_T("channel not found\n"));
494 }
495 else
496 {
497 if(m_pClient->DeleteChannel(pChl))
498 wxPrintf(_T("channel deleted\n"));
499 else
500 wxLogError(_T("%s"),m_pClient->GetLastError().c_str());
501 }
502 }
503 //--------------------------------------------------------
504 else if(str == _T("mv"))
505 {
506 wxString s;
507 TSPlayer ply;
508 TSPlayer *pPly;
509 TSChannel *pChl;
510
511 wxPrintf(_T("move player...\n"));
512 s = ReadString(_T("Name"));
513
514 pPly = m_pClient->FindPlayer(s);
515 if(pPly == NULL)
516 {
517 wxPrintf(_T("player not found\n"));
518 }
519 else
520 {
521 s = ReadString(_T("Channel"));
522 pChl = m_pClient->FindChannel(s);
523 if(pChl == NULL)
524 {
525 wxPrintf(_T("channel not found\n"));
526 }
527 else
528 {
529 ply.SetId(pPly->GetId());
530 ply.SetChannelId(pChl->GetId());
531
532 if(m_pClient->MovePlayer(&ply))
533 wxPrintf(_T("player moved\n"));
534 else
535 wxLogError(_T("%s"),m_pClient->GetLastError().c_str());
536 }
537 }
538 }
539 //--------------------------------------------------------
540 else if(str == _T("kick"))
541 {
542 wxString s;
543 TSPlayer ply;
544 TSPlayer *pPly;
545
546 wxPrintf(_T("kick player...\n"));
547 s = ReadString(_T("Name"));
548
549 pPly = m_pClient->FindPlayer(s);
550 if(pPly == NULL)
551 {
552 wxPrintf(_T("player not found\n"));
553 }
554 else
555 {
556 s = ReadString(_T("Message"));
557
558 ply.SetId(pPly->GetId());
559
560 if(m_pClient->KickPlayer(&ply,s))
561 wxPrintf(_T("player kicked\n"));
562 else
563 wxLogError(_T("%s"),m_pClient->GetLastError().c_str());
564 }
565
566 }
567 //--------------------------------------------------------
568 else if(str == _T("exit"))
569 break;
570 //--------------------------------------------------------
571 else if(str == _T("dump"))
572 {
573 m_pClient->Dump(out);
574 wxPrintf(_T("%s"), out.GetString().c_str());
575 }
576 //--------------------------------------------------------
577 else if(str == _T("connect"))
578 {
579 m_pClient->Disconnect();
580 wxPrintf(_T("connecting...\n"));
581 if(!m_pClient->Connect())
582 wxLogError(_T("%s, terminating."), m_pClient->GetLastError().c_str());
583 else
584 wxPrintf(_T("connected\n"));
585 }
586 //--------------------------------------------------------
587 else if(str == _T("disconnect"))
588 {
589 if(!m_pClient->Disconnect())
590 wxLogError(_T("%s, terminating."), m_pClient->GetLastError().c_str());
591 else
592 wxPrintf(_T("disconnected\n"));
593 }
594 //--------------------------------------------------------
595 else if(str == _T("help"))
596 {
597 wxPrintf(_T("pl show player list\n"));
598 wxPrintf(_T("cl show channel list\n"));
599 wxPrintf(_T("pcl player with channel list\n"));
600 wxPrintf(_T("cc create channel\n"));
601 wxPrintf(_T("dc delete channel\n"));
602 wxPrintf(_T("mv move player\n"));
603 wxPrintf(_T("kick kick player\n"));
604 wxPrintf(_T("mc modify channel\n"));
605 wxPrintf(_T("connect connect to server\n"));
606 wxPrintf(_T("disconnect disconnect from server\n"));
607 wxPrintf(_T("dump full object dump\n"));
608 wxPrintf(_T("exit exit application\n"));
609 }
610 } while(1);
611
612 return true;
613}
614
615//makes the application class known to wxWidgets for dynamic construction
616IMPLEMENT_APP_CONSOLE(TSApp)
617
diff --git a/tsapp.h b/tsapp.h
new file mode 100644
index 0000000..57de48c
--- /dev/null
+++ b/tsapp.h
@@ -0,0 +1,77 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef TSAPP_H
20#define TSAPP_H
21
22//libraries
23#include "tsclient.h"
24#include "tsquerythread.h"
25
26#include <wx/wx.h>
27#include <wx/ffile.h>
28#include <wx/fileconf.h>
29
30
31//config file name
32#define CONFIG_FILE_NAME _T("tsclient.cfg")
33//! Timeout for reconnect sec
34#define RECONNECT_TIMEOUT 10
35
36//Main application class
37class TSApp : public wxAppConsole
38{
39 public:
40 //main() replacment
41 virtual int OnRun();
42 //app cleanup
43 virtual int OnExit();
44 //app init
45 virtual bool OnInit();
46 //Command line parser
47 virtual void OnInitCmdLine(wxCmdLineParser &parser);
48 virtual bool OnCmdLineParsed(wxCmdLineParser &parser);
49 virtual bool OnCmdLineHelp(wxCmdLineParser &parser);
50 virtual bool OnCmdLineError(wxCmdLineParser &parser);
51 //interactive mode
52 bool Interactive();
53 //load config
54 bool LoadConfig(wxString const &filename);
55
56 private:
57 wxString ReadString(wxString const &str);
58
59 wxLogStderr *m_pLog;
60 wxFFile *m_pLogFile;
61 wxString m_pLogFileStr;
62 TSClient *m_pClient;
63 TSQueryThread*m_pQuery;
64 wxFileConfig *m_pConfig;
65 bool m_Interactive;
66 bool m_Logtostderr;
67 #if defined __UNIX__
68 bool m_Foreground;
69 #endif
70 wxString m_ConfigFileName;
71};
72
73//create a forward declaration of the wxGetApp
74//function implemented by IMPLEMENT_APP
75DECLARE_APP(TSApp)
76
77#endif
diff --git a/tschannel.cpp b/tschannel.cpp
new file mode 100644
index 0000000..d5530d1
--- /dev/null
+++ b/tschannel.cpp
@@ -0,0 +1,199 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tschannel.h"
21
22//Libraries
23#include <wx/txtstrm.h>
24
25IMPLEMENT_CLASS(TSChannel, wxObject)
26
27//------------------------------------------------------------------------------
28// Default CTor, Initializes the object.
29TSChannel::TSChannel()
30{
31 m_Id = 0;
32 m_Parent = TS_NO_PARENT;
33 m_Codec = 0;
34 m_Order = 3200;
35 m_Flags = 1;
36 m_MaxUsers = 4;
37 m_Users = 0;
38}
39
40//------------------------------------------------------------------------------
41// Default DTor.
42TSChannel::~TSChannel()
43{
44}
45
46//------------------------------------------------------------------------------
47// Sets the channel Id.
48bool TSChannel::SetId(wxUint32 const id)
49{
50 m_Id = id;
51 return true;
52}
53
54//------------------------------------------------------------------------------
55// Sets the channel name.
56bool TSChannel::SetName(wxString const &str)
57{
58 if(str.Length() == 0)
59 {
60 SetLastError(_T("empty string"));
61 return false;
62 }
63
64 m_Name = str;
65 return true;
66}
67
68//------------------------------------------------------------------------------
69// Sets the channel topic.
70bool TSChannel::SetTopic(wxString const &str)
71{
72 m_Topic = str;
73 return true;
74}
75
76//------------------------------------------------------------------------------
77// Sets the channel description.
78bool TSChannel::SetDescription(wxString const &str)
79{
80 m_Description = str;
81 return true;
82}
83
84//------------------------------------------------------------------------------
85// Sets the channel password.
86bool TSChannel::SetPassword(wxString const &str)
87{
88 if(str.Length() != 0)
89 m_Flags |= TS_PASSWORD;
90 else
91 m_Flags &= ~TS_PASSWORD;
92
93 m_Password = str;
94 return true;
95}
96
97//------------------------------------------------------------------------------
98// Sets the channel parent.
99bool TSChannel::SetParent(wxUint32 const parent)
100{
101 m_Parent = parent;
102 return true;
103}
104
105//------------------------------------------------------------------------------
106// Sets the channel codec.
107bool TSChannel::SetCodec(wxUint16 const codec)
108{
109 m_Codec = codec;
110 return true;
111}
112
113//------------------------------------------------------------------------------
114// Sets the channel order.
115bool TSChannel::SetOrder(wxUint16 const order)
116{
117 m_Order = order;
118 return true;
119}
120
121//------------------------------------------------------------------------------
122// Sets the channel flags.
123bool TSChannel::SetFlags(wxString const &str)
124{
125 wxUint16 flags = 1;
126
127 if(str.Find(wxChar('R')) != wxNOT_FOUND)
128 flags &= ~TS_UNREGISTRED;
129 else
130 flags |= TS_UNREGISTRED;
131
132 if(str.Find(wxChar('M')) != wxNOT_FOUND)
133 flags |= TS_MODERATE;
134 else
135 flags &= ~TS_MODERATE;
136
137 if(str.Find(wxChar('S')) != wxNOT_FOUND)
138 flags |= TS_HIERARCHICAL;
139 else
140 flags &= ~TS_HIERARCHICAL;
141
142 if(str.Find(wxChar('D')) != wxNOT_FOUND)
143 flags |= TS_DEFAULT;
144 else
145 flags &= ~TS_DEFAULT;
146
147 if(str.Find(wxChar('P')) != wxNOT_FOUND || m_Password.Length() != 0)
148 flags |= TS_PASSWORD;
149 else
150 flags &= ~TS_PASSWORD;
151
152 m_Flags = flags;
153 return true;
154}
155
156//------------------------------------------------------------------------------
157// Sets the channel flags.
158bool TSChannel::SetFlags(wxUint16 const flags)
159{
160 m_Flags = flags;
161 return true;
162}
163
164//------------------------------------------------------------------------------
165// Sets the channels maximum users count.
166bool TSChannel::SetMaxUsers(wxUint16 const users)
167{
168 m_MaxUsers = users;
169 return true;
170}
171
172//------------------------------------------------------------------------------
173// Sets the channels users count.
174bool TSChannel::SetUsers(wxUint16 const users)
175{
176 m_Users = users;
177 return true;
178}
179
180//------------------------------------------------------------------------------
181// Dumps object.
182void TSChannel::Dump(wxOutputStream &ostrm) const
183{
184 wxTextOutputStream out(ostrm);
185 out << _T("Object: TSChannel (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl;
186 out << _T("-wxUint32 m_Id: ") << wxString::Format(_T("0x%X"), m_Id) << endl;
187 out << _T("-wxString m_Name: ") << m_Name << endl;
188 out << _T("-wxString m_Topic: ") << m_Topic << endl;
189 out << _T("-wxString m_Description: ") << m_Description << endl;
190 out << _T("-wxString m_Password: ") << m_Password << endl;
191 out << _T("-wxUint32 m_Parent: ") << wxString::Format(_T("0x%X"), m_Parent) << endl;
192 out << _T("-wxUint16 m_Codec: ") << wxString::Format(_T("0x%X"), m_Codec) << endl;
193 out << _T("-wxUint16 m_Order: ") << wxString::Format(_T("0x%X"), m_Order) << endl;
194 out << _T("-wxUint16 m_Flags: ") << wxString::Format(_T("0x%X"), m_Flags) << endl;
195 out << _T("-wxUint16 m_MaxUsers: ") << wxString::Format(_T("0x%X"), m_MaxUsers) << endl;
196 out << _T("-wxUint16 m_Users: ") << wxString::Format(_T("0x%X"), m_Users) << endl;
197 out << _T("-wxString m_LastError: ") << m_LastError << endl;
198}
199
diff --git a/tschannel.h b/tschannel.h
new file mode 100644
index 0000000..a1b3855
--- /dev/null
+++ b/tschannel.h
@@ -0,0 +1,371 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef TSCHANNEL_H
20#define TSCHANNEL_H
21
22#include "tsheaders.h"
23
24// Libraries
25#include <wx/wx.h>
26
27//------------------------------------------------------------------------------
28//! Channel flags
29//! Unregistered:
30#define TS_UNREGISTRED 1
31//! Moderated:
32#define TS_MODERATE 2
33//! Password:
34#define TS_PASSWORD 4
35//! Hierarchical aka Subchannels:
36#define TS_HIERARCHICAL 8
37//! Default:
38#define TS_DEFAULT 16
39
40//------------------------------------------------------------------------------
41//! Channel Codecs
42//! CELP 5.2
43#define TS_CELP_5_2 0
44//! CELP 6.3
45#define TS_CELP_6_3 1
46//! GSM 14.8
47#define TS_GSM_14_8 2
48//! GSM 16.4
49#define TS_GSM_16_4 3
50//! Windows CELP 5.2
51#define TS_WINDOWS_CELP_5_2 4
52//! Speex 3.4
53#define TS_SPEEX_3_4 5
54//! Speex 5.2
55#define TS_SPEEX_5_2 6
56//! Speex 7.2
57#define TS_SPEEX_7_2 7
58//! Speex 9.3
59#define TS_SPEEX_9_3 8
60//! Speex 12.3
61#define TS_SPEEX_12_3 9
62//! Speex 16.3
63#define TS_SPEEX_16_3 10
64//! Speex 19.5
65#define TS_SPEEX_19_5 11
66//! Speex 25.9
67#define TS_SPEEX_25_9 12
68
69//!no parent channel
70#define TS_NO_PARENT 0xffffffff
71
72//! TeamSpeak channel.
73/*! TSChanel is used to hold all channel informations.
74 * After calling TSClient::Connect(), you can read
75 * out all the channel attributes. These stepps are
76 * necessary to connect to a server and read all information
77 * out.
78 * - Create a TSServer object,edit and link it to the TSClient object
79 * (For more information see TSClient)
80 * - Call TSClient::Connect()
81 * - Call TSClient::GetChannel() or GetChannels()
82 * - Now the class is filled up with the player information
83 */
84class TSChannel : public wxObject
85{
86 DECLARE_CLASS(TSChannel)
87 public:
88
89 /*! Default CTor, Initializes the object.
90 */
91 TSChannel();
92
93 /*! Default DTor.
94 */
95 ~TSChannel();
96
97 /*! Sets the channel Id.
98 * \param id channel Id.
99 * \return Returns false if fails, check GetLastError for details.
100 * \sa GetLastError()
101 */
102 bool SetId(wxUint32 const id);
103
104 /*! Sets the channel name.
105 * \param str Channel name.
106 * \return Returns false if fails, check GetLastError for details.
107 * \sa GetLastError()
108 */
109 bool SetName(wxString const &str);
110
111 /*! Sets the channel topic.
112 * \param str Channel topic.
113 * \return Returns false if fails, check GetLastError for details.
114 * \sa GetLastError()
115 */
116 bool SetTopic(wxString const &str);
117
118 /*! Sets the channel description.
119 * \param str Channel description.
120 * \return Returns false if fails, check GetLastError for details.
121 * \sa GetLastError()
122 */
123 bool SetDescription(wxString const &str);
124
125 /*! Sets the channel password.
126 * \param str Channel password.
127 * \return Returns false if fails, check GetLastError for details.
128 * \sa GetLastError()
129 */
130 bool SetPassword(wxString const &str);
131
132 /*! Sets the channel parent.
133 * \param parent Channel parent.
134 * \return Returns false if fails, check GetLastError for details.
135 * \sa GetLastError()
136 */
137 bool SetParent(wxUint32 const parent);
138
139 /*! Sets the channel codec.
140 * - CELP 5.2: 0
141 * - CELP 6.3: 1
142 * - GSM 14.8: 2
143 * - GSM 16.4: 3
144 * - Windows CELP 5.2: 4
145 * - Speex 3.4: 5
146 * - Speex 5.2: 6
147 * - Speex 7.2: 7
148 * - Speex 9.3: 8
149 * - Speex 12.3: 9
150 * - Speex 16.3: 10
151 * - Speex 19.5: 11
152 * - Speex 25.9: 12
153 * \param codec Channel codec.
154 * \return Returns false if fails, check GetLastError for details.
155 * \sa GetLastError()
156 */
157 bool SetCodec(wxUint16 const codec);
158
159 /*! Sets the channel order.
160 * \param order Channel order.
161 * \return Returns false if fails, check GetLastError for details.
162 * \sa GetLastError()
163 */
164 bool SetOrder(wxUint16 const order);
165
166 /*! Sets the channel flags.
167 * - Unregistered: 1
168 * - Moderated: 2
169 * - Password: 4
170 * - Hierarchical: 8
171 * - Default: 16
172 * \param flags Channel flags.
173 * \return Returns false if fails, check GetLastError for details.
174 * \sa GetLastError()
175 */
176 bool SetFlags(wxUint16 const flags);
177
178 /*! Sets the channel flags.
179 * - Registered: R
180 * - Moderated: M
181 * - Password: P
182 * - Hierarchical: S
183 * - Default: D
184 * \param flags Channel flags.
185 * \return Returns false if fails, check GetLastError for details.
186 * \sa GetLastError()
187 */
188 bool SetFlags(wxString const &str);
189
190 /*! Sets the channels maximum users count.
191 * \param users Channel maximum users count.
192 * \return Returns false if fails, check GetLastError for details.
193 * \sa GetLastError()
194 */
195 bool SetMaxUsers(wxUint16 const users);
196
197 /*! Sets the channels users count.
198 * \param users Channel maximum users count.
199 * \return Returns false if fails, check GetLastError for details.
200 * \sa GetLastError()
201 */
202 bool SetUsers(wxUint16 const users);
203
204 /*! Gets the channel id.
205 * \return Channel Id.
206 */
207 wxUint32 GetId() const
208 {
209 return m_Id;
210 }
211
212 /*! Gets the channel name.
213 * \return Channel name.
214 */
215 wxString const &GetName() const
216 {
217 return m_Name;
218 }
219
220 /*! Gets the channel topic.
221 * \return Channel topic.
222 */
223 wxString const &GetTopic() const
224 {
225 return m_Topic;
226 }
227
228 /*! Gets the channel description.
229 * \return Channel description.
230 */
231 wxString const &GetDescription() const
232 {
233 return m_Description;
234 }
235
236 /*! Gets the channel password.
237 * \return Channel password.
238 */
239 wxString const &GetPassword() const
240 {
241 return m_Password;
242 }
243
244 /*! Gets the channel parent.
245 * \return Channel parent.
246 */
247 wxUint32 GetParent() const
248 {
249 return m_Parent;
250 }
251
252 /*! Gets the channel codec.
253 * - CELP 5.2: 0
254 * - CELP 6.3: 1
255 * - GSM 14.8: 2
256 * - GSM 16.4: 3
257 * - Windows CELP 5.2: 4
258 * - Speex 3.4: 5
259 * - Speex 5.2: 6
260 * - Speex 7.2: 7
261 * - Speex 9.3: 8
262 * - Speex 12.3: 9
263 * - Speex 16.3: 10
264 * - Speex 19.5: 11
265 * - Speex 25.9: 12
266 * \return Channel codec.
267 */
268 wxUint16 GetCodec() const
269 {
270 return m_Codec;
271 }
272
273 /*! Gets the channel order.
274 * \return Channel order.
275 */
276 wxUint16 GetOrder() const
277 {
278 return m_Order;
279 }
280
281 /*! Gets the channel flags.
282 * - Unregistered: 1
283 * - Moderated: 2
284 * - Password: 4
285 * - Hierarchical: 8
286 * - Default: 16
287 * \return Channel flags.
288 */
289 wxUint16 GetFlags() const
290 {
291 return m_Flags;
292 }
293
294 /*! Gets the channel flags.
295 * - Unregistered: 1
296 * - Moderated: 2
297 * - Password: 4
298 * - Hierarchical: 8
299 * - Default: 16
300 * \return Channel flags.
301 */
302 wxString const GetFlagsString() const
303 {
304 wxString str;
305 if((m_Flags &TS_MODERATE))
306 str += _T("M");
307 if((m_Flags &TS_DEFAULT))
308 str += _T("D");
309 if((m_Flags &TS_HIERARCHICAL))
310 str += _T("S");
311 if((m_Flags &TS_PASSWORD))
312 str += _T("P");
313 if(!(m_Flags &TS_UNREGISTRED))
314 str += _T("R");
315 return str;
316 }
317 /*! Gets the channel max users.
318 * \return Channel max users.
319 */
320 wxUint16 GetMaxUsers() const
321 {
322 return m_MaxUsers;
323 }
324
325 /*! Gets the channel user count.
326 * \return Channel user count.
327 */
328 wxUint16 GetUsers() const
329 {
330 return m_Users;
331 }
332
333 /*! Gets the LastError message, call this method
334 * to get more information for an error.
335 * \return LastError message.
336 */
337 wxString const &GetLastError() const
338 {
339 return m_LastError;
340 }
341
342 /*! Dumps object.
343 * \param ostrm Stream to write.
344 */
345 void Dump(wxOutputStream &ostrm) const;
346
347
348 private:
349
350 //Sets the LastError message.
351 void SetLastError(wxString const &str)
352 {
353 m_LastError = str;
354 }
355
356 //members
357 wxUint32 m_Id;
358 wxString m_Name;
359 wxString m_Topic;
360 wxString m_Description;
361 wxString m_Password;
362 wxUint32 m_Parent;
363 wxUint16 m_Codec;
364 wxUint16 m_Order;
365 wxUint16 m_Flags;
366 wxUint16 m_MaxUsers;
367 wxUint16 m_Users;
368 wxString m_LastError;
369};
370
371#endif
diff --git a/tsclient.cfg b/tsclient.cfg
new file mode 100644
index 0000000..218756f
--- /dev/null
+++ b/tsclient.cfg
@@ -0,0 +1,52 @@
1#*******************************************
2# TeamSpeak daemon
3# (c)2005 clan-server.at
4#*******************************************
5
6#-------------------------------------------
7# TeamSpeak client scecific settings
8#-------------------------------------------
9
10# TeamSpeak client Platform description
11TSPlatform = Windows XP
12
13# TeamSpeak client version number (e.g. "2.0.32.60")
14TSVersionNumber = 2.0.32.60
15
16# TeamSpeak player login name
17# If string is empty, login as anonymous.
18TSLoginName = username
19
20# TeamSpeak player password
21TSLoginPassword = password
22
23# TeamSpeak player nickname
24TSNickname = tsdaemon
25
26# TeamSpeak server IP address or URL
27TSServerAddress = localhost
28
29# TeamSpeak server port
30TSPort = 8767
31
32#-------------------------------------------
33# TeamSpeak daemon scecific settings
34#-------------------------------------------
35
36#Daemon logfile
37#if string is empty, no logfile.
38LogFile = tsclient.log
39
40# Daemon host address, can be IP or URL
41# If string is empty or 0.0.0.0, bind to any interfaces.
42ServerAddress = 0.0.0.0
43
44# Daemon allowed IP-Addresses
45# Separate with ','
46AllowedAddresses = 127.0.0.1
47
48# Daemon listening port
49Port = 54321
50
51# Daemon password
52Password = daemon_password
diff --git a/tsclient.cpp b/tsclient.cpp
new file mode 100644
index 0000000..95f7e53
--- /dev/null
+++ b/tsclient.cpp
@@ -0,0 +1,760 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tsclient.h"
21
22//Libraries
23#include <wx/wfstream.h>
24#include <wx/stream.h>
25#include <wx/sstream.h>
26#include <wx/socket.h>
27#include <wx/mstream.h>
28#include <wx/buffer.h>
29#include <wx/sckstrm.h>
30#include <wx/utils.h>
31#include <wx/memory.h>
32#include <wx/txtstrm.h>
33#include <wx/regex.h>
34
35IMPLEMENT_CLASS(TSClient, wxObject)
36IMPLEMENT_CLASS(TSCmd, wxObject)
37
38//------------------------------------------------------------------------------
39// Default CTor, Initializes the object.
40TSClient::TSClient()
41{
42 //create all objects
43 m_pMutex = new wxMutex;
44 m_pPlayer = new TSPlayer;
45 m_ppPlayers = new TSpPlayerArray;
46 m_pChannel = new TSChannel;
47 m_ppChannels = new TSpChannelArray;
48 m_pConnection = NULL;
49 m_pServer = new TSServer;
50 m_pSync = NULL;
51 m_VersionNumber = _T("0.0.0.0");
52 m_Platform = _T("na");
53 m_LastError = _T("");
54 m_SessionId = 0;
55 m_pReconnectAct = true;
56}
57
58//------------------------------------------------------------------------------
59// Default DTor.
60TSClient::~TSClient()
61{
62 //do the necessary cleanup
63 wxASSERT(m_pPlayer != NULL);
64 delete m_pPlayer;
65 m_pPlayer = NULL;
66
67 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
68 {
69 wxASSERT(m_ppPlayers != NULL);
70 delete m_ppPlayers->Item(i);
71 }
72
73 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
74 {
75 wxASSERT(m_ppChannels != NULL);
76 delete m_ppChannels->Item(i);
77 }
78
79 wxASSERT(m_ppPlayers != NULL);
80 delete m_ppPlayers;
81 m_ppPlayers = NULL;
82
83 wxASSERT(m_pChannel != NULL);
84 delete m_pChannel;
85 m_pChannel = NULL;
86
87 wxASSERT(m_ppChannels != NULL);
88 delete m_ppChannels;
89 m_ppChannels = NULL;
90
91 wxASSERT(m_pServer != NULL);
92 delete m_pServer;
93 m_pServer = NULL;
94
95 if(m_pConnection != NULL)
96 {
97 delete m_pConnection;
98 m_pConnection = NULL;
99 }
100}
101
102//------------------------------------------------------------------------------
103// Send a command to a Teasmpeak server.
104bool TSClient::SendCommand(wxUint32 cmd)
105{
106 TSCmd sync;
107 sync.id = cmd;
108 sync.error = false;
109 sync.client = this;
110 return SendCommand(&sync);
111}
112
113//------------------------------------------------------------------------------
114// Send a command to a Teamspeak server.
115bool TSClient::SendCommand(TSCmd *cmd)
116{
117 if(!m_pConnection->IsAlive())
118 {
119 SetLastError(_T("thread not running"));
120 return false;
121 }
122
123 m_pMutex->Lock();
124
125 m_Lock = true;
126 m_pSync = cmd;
127
128 m_pMutex->Unlock();
129
130 bool error = true;
131 for(int i=0;i<THREAD_TIMEOUT;i++)
132 {
133 m_pMutex->Lock();
134 if (!m_Lock)
135 {
136 error = false;
137 break;
138 }
139 m_pMutex->Unlock();
140 wxMilliSleep(1);
141 }
142
143 if(error)
144 {
145 SetLastError(_T("thread not responding"));
146 m_pMutex->Unlock();
147 return false;
148 }
149
150 cmd = m_pSync;
151 m_pSync = NULL;
152
153 if(cmd == NULL)
154 {
155 SetLastError(_T("command is NULL"));
156 m_pMutex->Unlock();
157 return false;
158 }
159
160 if(cmd->error)
161 {
162 SetLastError(cmd->lasterror);
163 m_pMutex->Unlock();
164 return false;
165 }
166
167 if(!cmd->executed)
168 {
169 SetLastError(_T("command not executed"));
170 m_pMutex->Unlock();
171 return false;
172 }
173
174 m_pMutex->Unlock();
175 return true;
176}
177
178//------------------------------------------------------------------------------
179// Connects to a Teasmpeak server.
180bool TSClient::Connect()
181{
182 if(m_pPlayer == NULL)
183 {
184 SetLastError(_T("no player object"));
185 return false;
186 }
187
188 if(m_pServer == NULL)
189 {
190 SetLastError(_T("no server object"));
191 return false;
192 }
193
194 if(m_pConnection == NULL)
195 {
196 //m_pMutex->Lock();
197 m_pConnection = new TSConnectionThread(this, m_pMutex);
198 //Start thread
199 m_pConnection->Run();
200 }
201
202 if(!m_pConnection->IsAlive())
203 {
204 SetLastError(_T("can't create thread"));
205 return false;
206 }
207
208 if(!SendCommand(TS_CMD_SEND_LOGIN))
209 return false;
210
211 if(!SendCommand(TS_CMD_SEND_DEFAULT))
212 return false;
213
214 return true;
215}
216
217//------------------------------------------------------------------------------
218// Disconnects from a Teasmpeak server.
219bool TSClient::Disconnect(bool reconnect)
220{
221 if(IsConnected())
222 if(!SendCommand(TS_CMD_SEND_LOGOUT))
223 return false;
224
225 wxSleep(1);
226 if(m_pConnection != NULL)
227 {
228 m_pConnection->Delete();
229 delete m_pConnection;
230 m_pConnection = NULL;
231 }
232
233 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
234 {
235 wxASSERT(m_ppPlayers != NULL);
236 delete m_ppPlayers->Item(i);
237 }
238 m_ppPlayers->Empty();
239
240 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
241 {
242 wxASSERT(m_ppChannels != NULL);
243 delete m_ppChannels->Item(i);
244 }
245 m_ppChannels->Empty();
246
247 m_pReconnectAct = reconnect;
248
249 return true;
250}
251
252//------------------------------------------------------------------------------
253// Sets the platform string (e.g. Windows XP, Linux).
254bool TSClient::SetPlatform(wxString const &str)
255{
256 if(str.Length() == 0)
257 {
258 SetLastError(_T("empty string"));
259 return false;
260 }
261
262 m_Platform = str;
263 return true;
264}
265
266//------------------------------------------------------------------------------
267// Sets the TeamSpeak player.
268bool TSClient::SetPlayer(TSPlayer *pPlayer)
269{
270 if(pPlayer == NULL)
271 {
272 SetLastError(_T("invalid pointer"));
273 return false;
274 }
275
276 wxASSERT(m_pPlayer != NULL);
277 delete m_pPlayer;
278 m_pPlayer = pPlayer;
279
280 return true;
281}
282
283//------------------------------------------------------------------------------
284// Sets the TeamSpeak player channel.
285bool TSClient::SetChannel(TSChannel *pChannel)
286{
287 if(pChannel == NULL)
288 {
289 SetLastError(_T("invalid pointer"));
290 return false;
291 }
292
293 if(m_pChannel != NULL)
294 delete m_pChannel;
295 m_pChannel = pChannel;
296
297 return true;
298}
299
300//------------------------------------------------------------------------------
301// Sets the TeamSpeak server.
302bool TSClient::SetServer(TSServer *pServer)
303{
304 if(pServer == NULL)
305 {
306 SetLastError(_T("invalid pointer"));
307 return false;
308 }
309
310 if(m_pServer != NULL)
311 delete m_pServer;
312 m_pServer = pServer;
313
314 return true;
315}
316
317//------------------------------------------------------------------------------
318// Sets the TeamSpeak connection.
319bool TSClient::SetConnection(TSConnectionThread *pConnection)
320{
321 if(pConnection == NULL)
322 {
323 SetLastError(_T("invalid pointer"));
324 return false;
325 }
326
327 if(m_pConnection != NULL)
328 delete m_pConnection;
329 m_pConnection = pConnection;
330
331 return true;
332}
333
334//------------------------------------------------------------------------------
335// Sets the TeamSpeak client version number
336bool TSClient::SetVersionNumber(wxString const &str)
337{
338 if(str.Length() == 0)
339 {
340 SetLastError(_T("empty string"));
341 return false;
342 }
343
344 m_VersionNumber = str;
345 return true;
346}
347
348//------------------------------------------------------------------------------
349// Sets the session id.
350bool TSClient::SetSessionId(wxUint32 const id)
351{
352 m_SessionId = id;
353 return true;
354}
355
356//------------------------------------------------------------------------------
357// Sets Sync onject, for thread sync.
358bool TSClient::SetSync(TSCmd *sync)
359{
360 m_pSync = sync;
361 return true;
362}
363
364//------------------------------------------------------------------------------
365// FindPlayer.
366TSPlayer *TSClient::FindPlayer(wxUint32 id)
367{
368 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
369 {
370 if(m_ppPlayers->Item(i)->GetId() == id)
371 return m_ppPlayers->Item(i);
372 }
373
374 SetLastError(_T("player not found"));
375 return NULL;
376}
377
378//------------------------------------------------------------------------------
379// FindPlayer.
380TSPlayer *TSClient::FindPlayer(wxString const &str)
381{
382 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
383 {
384 if(m_ppPlayers->Item(i)->GetNickname() == str)
385 return m_ppPlayers->Item(i);
386 }
387
388 SetLastError(_T("player not found"));
389 return NULL;
390}
391
392//------------------------------------------------------------------------------
393// FindChannel.
394TSChannel *TSClient::FindChannel(wxUint32 id)
395{
396 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
397 {
398 if(m_ppChannels->Item(i)->GetId() == id)
399 return m_ppChannels->Item(i);
400 }
401
402 SetLastError(_T("channel not found"));
403 return NULL;
404}
405
406//------------------------------------------------------------------------------
407// FindChannel.
408TSChannel *TSClient::FindChannel(wxString const &str)
409{
410 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
411 {
412 if(m_ppChannels->Item(i)->GetName() == str)
413 return m_ppChannels->Item(i);
414 }
415
416 SetLastError(_T("channel not found"));
417 return NULL;
418}
419
420//------------------------------------------------------------------------------
421// Finds default channel
422TSChannel *TSClient::FindDefaultChannel()
423{
424 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
425 {
426 if((m_ppChannels->Item(i)->GetFlags() &TS_DEFAULT))
427
428 return m_ppChannels->Item(i);
429 }
430
431 SetLastError(_T("channel not found"));
432 return NULL;
433}
434
435//------------------------------------------------------------------------------
436// FindChannelsByParent.
437bool TSClient::FindChannelsByParent(wxUint32 id, TSpChannelArray *channels)
438{
439 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
440 {
441 if(m_ppChannels->Item(i)->GetParent() == id)
442 channels->Add(m_ppChannels->Item(i));
443 }
444
445 if(channels->GetCount() == 0)
446 {
447 SetLastError(_T("no channels found"));
448 return false;
449 }
450
451 return true;
452}
453
454//------------------------------------------------------------------------------
455// FindChannelsByName.
456bool TSClient::FindChannelsByName(wxString const &str, TSpChannelArray *channels)
457{
458 wxRegEx regex;
459 regex.Compile(str);
460 if(!regex.IsValid())
461 {
462 SetLastError(_T("regular expressions pattern error"));
463 return false;
464 }
465
466 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
467 {
468 if(regex.Matches(m_ppChannels->Item(i)->GetName()))
469 channels->Add(m_ppChannels->Item(i));
470 }
471
472 if(channels->GetCount() == 0)
473 {
474 SetLastError(_T("no channels found"));
475 return false;
476 }
477
478 return true;
479}
480
481//------------------------------------------------------------------------------
482// FindPlayersByName.
483bool TSClient::FindPlayersByName(wxString const &str, TSpPlayerArray *players)
484{
485 wxRegEx regex;
486 regex.Compile(str);
487 if(!regex.IsValid())
488 {
489 SetLastError(_T("regular expressions pattern error"));
490 return false;
491 }
492
493 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
494 {
495 if(regex.Matches(m_ppPlayers->Item(i)->GetNickname()))
496 players->Add(m_ppPlayers->Item(i));
497 }
498
499 if(players->GetCount() == 0)
500 {
501 SetLastError(_T("no player found"));
502 return false;
503 }
504
505 return true;
506}
507
508//------------------------------------------------------------------------------
509// Finds all players in channel.
510bool TSClient::FindPlayersByChannel(TSChannel *channel, TSpPlayerArray *players)
511{
512 if(channel == NULL)
513 {
514 SetLastError(_T("invalid pointer"));
515 return false;
516 }
517
518 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
519 {
520 if(m_ppPlayers->Item(i)->GetChannelId() == channel->GetId())
521 players->Add(m_ppPlayers->Item(i));
522 }
523
524 if(players->GetCount() == 0)
525 {
526 SetLastError(_T("no player found"));
527 return false;
528 }
529 return true;
530}
531
532//------------------------------------------------------------------------------
533// Creates a channel.
534bool TSClient::CreateChannel(TSChannel *channel)
535{
536 if(channel == NULL)
537 {
538 SetLastError(_T("invalid pointer"));
539 return false;
540 }
541
542 TSCmd sync;
543 sync.id = TS_CMD_SEND_ADD_CHANNEL;
544 sync.client = this;
545 sync.param1.pChannel = channel;
546
547 if(!SendCommand(&sync))
548 return false;
549 return true;
550}
551
552//------------------------------------------------------------------------------
553// Deletes a channel.
554bool TSClient::DeleteChannel(TSChannel *channel)
555{
556 if(channel == NULL)
557 {
558 SetLastError(_T("invalid pointer"));
559 return false;
560 }
561
562 TSCmd sync;
563 sync.id = TS_CMD_SEND_DEL_CHANNEL;
564 sync.client = this;
565 sync.param1.pChannel = channel;
566
567 if(!SendCommand(&sync))
568 return false;
569 return true;
570}
571
572//------------------------------------------------------------------------------
573// Moves a Player.
574bool TSClient::MovePlayer(TSPlayer *player)
575{
576 if(player == NULL)
577 {
578 SetLastError(_T("invalid pointer"));
579 return false;
580 }
581
582 TSCmd sync;
583 sync.id = TS_CMD_SEND_MOVE_PLAYER;
584 sync.client = this;
585 sync.param1.pPlayer = player;
586
587 if(!SendCommand(&sync))
588 return false;
589 return true;
590}
591
592//------------------------------------------------------------------------------
593// Modify Channel.
594bool TSClient::ModifyChannel(TSChannel *channel)
595{
596 if(channel == NULL)
597 {
598 SetLastError(_T("invalid pointer"));
599 return false;
600 }
601
602 if(channel->GetPassword().Length()!= 0)
603 {
604 TSCmd sync;
605 sync.id = TS_CMD_SEND_SET_CHANNEL_PASSWORD;
606 sync.client = this;
607 sync.param1.pChannel = channel;
608
609 if(!SendCommand(&sync))
610 return false;
611 }
612
613 {
614 TSCmd sync;
615 sync.id = TS_CMD_SEND_SET_CHANNEL_FLAGSCODEC;
616 sync.client = this;
617 sync.param1.pChannel = channel;
618
619 if(!SendCommand(&sync))
620 return false;
621 }
622
623 {
624 TSCmd sync;
625 sync.id = TS_CMD_SEND_SET_CHANNEL_NAME;
626 sync.client = this;
627 sync.param1.pChannel = channel;
628
629 if(!SendCommand(&sync))
630 return false;
631 }
632
633 {
634 TSCmd sync;
635 sync.id = TS_CMD_SEND_SET_CHANNEL_TOPIC;
636 sync.client = this;
637 sync.param1.pChannel = channel;
638
639 if(!SendCommand(&sync))
640 return false;
641 }
642
643 {
644 TSCmd sync;
645 sync.id = TS_CMD_SEND_SET_CHANNEL_DESCRIPTION;
646 sync.client = this;
647 sync.param1.pChannel = channel;
648
649 if(!SendCommand(&sync))
650 return false;
651 }
652
653 {
654 TSCmd sync;
655 sync.id = TS_CMD_SEND_SET_CHANNEL_MAXPLAYERS;
656 sync.client = this;
657 sync.param1.pChannel = channel;
658
659 if(!SendCommand(&sync))
660 return false;
661 }
662
663#if 0
664 {
665 TSCmd sync;
666 sync.id = TS_CMD_SEND_SET_CHANNEL_ORDER;
667 sync.client = this;
668 sync.param1.pChannel = channel;
669
670 if(!SendCommand(&sync))
671 return false;
672 }
673#endif
674
675 return true;
676}
677
678//------------------------------------------------------------------------------
679// Check if connected.
680bool TSClient::IsConnected()
681{
682 if(m_pConnection != NULL)
683 return m_pConnection->m_Connected;
684 return false;
685}
686
687//------------------------------------------------------------------------------
688// Kick a Player.
689bool TSClient::KickPlayer(TSPlayer *player, wxString msg)
690{
691 if(player == NULL)
692 {
693 SetLastError(_T("invalid pointer"));
694 return false;
695 }
696
697 TSCmd sync;
698 sync.id = TS_CMD_SEND_KICK_PLAYER;
699 sync.client = this;
700 sync.param1.pPlayer = player;
701 sync.param2.pString = &msg;
702
703 if(!SendCommand(&sync))
704 return false;
705 return true;
706}
707
708//------------------------------------------------------------------------------
709// Dumps object.
710void TSClient::Dump(wxOutputStream &ostrm) const
711{
712 wxTextOutputStream out(ostrm);
713 out << wxString(_T("-"), 60) << endl;
714 out << _T("Object: TSClient (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl;
715 out << wxString(_T("-"), 60) << endl;
716 out << _T("-TSPlayer *m_pPlayer:") << endl;
717 m_pPlayer->Dump(ostrm);
718 out << endl;
719
720 //TSpPlayerArray
721 out << wxString(_T("-"), 60) << endl;
722 out << _T("-TSpPlayerArray *m_ppPlayers:") << endl;
723 out << _T(" total objects: ") << wxUint32(m_ppPlayers->GetCount()) << endl;
724 for(size_t i = 0; i < m_ppPlayers->GetCount(); i++)
725 {
726 out << _T("\n*Item: ") << wxUint32(i) << endl;
727 m_ppPlayers->Item(i)->Dump(ostrm);
728 }
729 out << endl;
730
731 out << wxString(_T("-"), 60) << endl;
732 out << _T("-TSChannel *m_pChannel:") << endl;
733 m_pChannel->Dump(ostrm);
734 out << endl;
735
736 //TSpChannelArray
737 out << wxString(_T("-"), 60) << endl;
738 out << _T("-TSpChannelArray *m_ppChannels:") << endl;
739 out << _T(" total objects: ") << wxUint32(m_ppChannels->GetCount()) << endl;
740 for(size_t i = 0; i < m_ppChannels->GetCount(); i++)
741 {
742 out << _T("\n*Item: ") << wxUint32(i) << endl;
743 m_ppChannels->Item(i)->Dump(ostrm);
744 }
745 out << endl;
746
747 //TSServer
748 out << wxString(_T("-"), 60) << endl;
749 out << _T("-TSServer *m_pServer:") << endl;
750 m_pServer->Dump(ostrm);
751 out << endl;
752
753 //remaining members
754 out << wxString(_T("-"), 60) << endl;
755 out << _T("-wxString m_VersionNumber: ") << m_VersionNumber << endl;
756 out << _T("-wxString m_Platform: ") << m_Platform << endl;
757 out << _T("-wxUint32 m_SessionId: ") << wxString::Format(_T("0x%X"), m_SessionId) << endl;
758 out << _T("-wxString m_LastError: ") << m_LastError << endl;
759}
760
diff --git a/tsclient.h b/tsclient.h
new file mode 100644
index 0000000..ccc32b0
--- /dev/null
+++ b/tsclient.h
@@ -0,0 +1,489 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19//Header guard
20#ifndef TSCLIENT_H
21#define TSCLIENT_H
22
23//Libraries
24#include <wx/wx.h>
25#include <wx/thread.h>
26
27#include "tsheaders.h"
28#include "tsserver.h"
29
30//! Thread response timeout
31#define THREAD_TIMEOUT 4000
32
33//! Maximum time to leave
34#define MAX_TTL 5
35
36// better than void *
37union TSPtr
38{
39 TSPlayer *pPlayer;
40 TSChannel *pChannel;
41 TSServer *pServer;
42 TSClient *pClient;
43 wxString *pString;
44};
45
46//! Only for internal use
47struct TSCmd : wxObject
48{
49 DECLARE_CLASS(TSCmd)
50 //CTor
51 TSCmd()
52 {
53 id = 0;
54 executed = false;
55 error = false;
56 ttl = MAX_TTL;
57 pktid = 0;
58 oldid = 0;
59 client = NULL;
60 param1.pPlayer = NULL;
61 param1.pPlayer = NULL;
62 }
63
64 TSCmd(wxUint32 c)
65 {
66 TSCmd();
67 id = c;
68 }
69
70 TSCmd(wxUint32 c, TSCmd *old)
71 {
72 TSCmd();
73 id = c;
74 pktid = old->pktid;
75 oldid = old->id;
76 client = old->client;
77 }
78
79 TSCmd(const TSCmd &cmd)
80 : wxObject()
81 {
82 id = cmd.id;
83 oldid = cmd.oldid;
84 executed = cmd.executed;
85 error = cmd.error;
86 ttl = cmd.ttl;
87 pktid = cmd.pktid;
88 client = cmd.client;
89 param1 = cmd.param1;
90 param2 = cmd.param2;
91 lasterror = cmd.lasterror;
92 }
93
94 wxUint32 id;
95 wxUint32 oldid;
96 bool executed;
97 bool error;
98 wxUint32 ttl;
99 wxUint32 pktid;
100 TSClient *client;
101 TSPtr param1;
102 TSPtr param2;
103 wxString lasterror;
104};
105
106//! TeamSpeak client, main class.
107/*! TSClient is the main class to connect to a
108 * TeamSpeak server. These stepps are necessary
109 * to create and use a TSClient object.
110 * - Create a TSClient object.
111 * - Change the attributes.
112 * - Create a TSPlayer object.
113 * - Change the attributes.
114 * - Link it to the TSClient object.
115 * - Create a TSServer object.
116 * - Change the attributes.
117 * - Link it to the TSClient object.
118 * - Call Connect().
119 *
120 * Example:
121 * \code
122 *
123 * TSClient *pTSC = new TSClient;
124 * pTSC->SetPlatform(_T("Windows XP"));
125 * pTSC->SetVersionNumber(_T("2.0.32.60"));
126 *
127 * TSPlayer *pTSP = new TSPlayer;
128 * pTSP->SetLoginName(_T("admin"));
129 * pTSP->SetLoginPassword(_T("testpassword"));
130 * pTSP->SetNickname(_T("penner"));
131 * //now the TSClient takes care of the pointer.
132 * pTSC->SetPlayer(pTSP);
133 *
134 * TSServer *pTSS = new TSServer;
135 * pTSS->SetServerAddress(_T("game3.clan-server.at"));
136 * pTSS->SetPort(8767);
137 * //now the TSClient takes care of the pointer.
138 * pTSC->SetServer(pTSS);
139 *
140 * if(!pTSC->Connect())
141 * {
142 * wxLogError(_T("%s, terminating.\n"), pTSC->GetLastError().c_str());
143 * return EXIT_FAILURE;
144 * }
145 *
146 * pTSC->Disconnect();
147 * delete pTSC;
148 * \endcode
149 */
150class TSClient : public wxObject
151{
152 DECLARE_CLASS(TSClient)
153
154 public:
155
156 /*! Default CTor, Initializes the object.
157 * Creates all necessary member objects.
158 */
159 TSClient();
160
161 /*! Default DTor.
162 */
163 ~TSClient();
164
165 /*! Connects to a Teasmpeak server.
166 * \return Returns false if fails, check GetLastError for details.
167 * \sa GetLastError()
168 */
169 bool Connect();
170
171 /*! Disconnects from a Teasmpeak server.
172 * \return Returns false if fails, check GetLastError for details.
173 * \sa GetLastError()
174 */
175 bool Disconnect(bool reconnect = true);
176
177 /*! Sets the platform string (e.g. Windows XP, Linux).
178 * \param str Platform string.
179 * \return Returns false if fails, check GetLastError for details.
180 * \sa GetLastError()
181 */
182 bool SetPlatform(wxString const &str);
183
184 /*! Sets the TeamSpeak player.
185 * The class takes care of the pointer, no delete call.
186 * \param pPlayer TeamSpeak Player.
187 * \return Returns false if fails, check GetLastError for details.
188 * \sa TSPlayer GetLastError()
189 */
190 bool SetPlayer(TSPlayer *pPlayer);
191
192 /*! Sets the TeamSpeak player channel.
193 * The class takes care of the pointer, no delete call.
194 * \param pChannel player channel.
195 * \return Returns false if fails, check GetLastError for details.
196 * \sa TSChannel GetLastError()
197 */
198 bool SetChannel(TSChannel *pChannel);
199
200 /*! Sets the TeamSpeak server.
201 * The class takes care of the pointer, no delete call.
202 * \param pServer Server to use for connection.
203 * \return Returns false if fails, check GetLastError for details.
204 * \sa TSServer GetLastError()
205 */
206 bool SetServer(TSServer *pServer);
207
208 /*! Sets the TeamSpeak connection.
209 * The class takes care of the pointer, no delete call.
210 * \param pConnection Connection object.
211 * \return Returns false if fails, check GetLastError for details.
212 * \sa TSConnection GetLastError()
213 */
214 bool SetConnection(TSConnectionThread *pConnection);
215
216 /*! Sets the TeamSpeak client version number (e.g. "2.0.32.60").
217 * \param str Client version number.
218 * \return Returns false if fails, check GetLastError for details.
219 * \sa TSConnection GetLastError()
220 */
221 bool SetVersionNumber(wxString const &str);
222
223 /*! Sets the session id.
224 * \param id Session id.
225 * \return Returns false if fails, check GetLastError for details.
226 * \sa GetLastError()
227 */
228 bool SetSessionId(wxUint32 const id);
229
230 /*! Check if connected.
231 * \return Returns true if connected.
232 * \sa GetLastError()
233 */
234 bool IsConnected();
235
236 /*! Returns the state of the reconnectflag
237 * \return Returns false if fails, check GetLastError for details.
238 * \sa GetLastError()
239 */
240 bool IsReconnectActive()
241 {
242 return m_pReconnectAct;
243 }
244
245 /*! Sets Sync onject, for thread sync.
246 * \param sync Sync onject.
247 * \return Returns false if fails, check GetLastError for details.
248 * \sa GetLastError()
249 */
250 bool SetSync(TSCmd *sync);
251
252 /*! Gets the TeamSpeak client Platform string.
253 * \return Client Platform string.
254 */
255 wxString const &GetPlatform() const
256 {
257 return m_Platform;
258 }
259
260 /*! Gets the LastError message, call this method
261 * to get more information for an error.
262 * \return LastError message.
263 */
264 wxString const &GetLastError() const
265 {
266 return m_LastError;
267 }
268
269 /*! Gets the version number
270 * \return Version number.
271 */
272 wxString const &GetVersionNumber() const
273 {
274 return m_VersionNumber;
275 }
276
277 /*! Gets the TeamSpeak player.
278 * \return TeamSpeak player.
279 * \sa TSPlayer
280 */
281 TSPlayer *GetPlayer() const
282 {
283 return m_pPlayer;
284 }
285
286 /*! Gets all TeamSpeak players on the server.
287 * \return TeamSpeak players.
288 * \sa TSPlayer
289 */
290 TSpPlayerArray *GetPlayers() const
291 {
292 return m_ppPlayers;
293 }
294
295 /*! Gets the TeamSpeak channel.
296 * \return TeamSpeak channel.
297 * \sa TSChannel
298 */
299 TSChannel *GetChannel() const
300 {
301 return m_pChannel;
302 }
303
304 /*! Gets all TeamSpeak channels on the server.
305 * \return TeamSpeak channels.
306 * \sa TSChannel
307 */
308 TSpChannelArray *GetChannels() const
309 {
310 return m_ppChannels;
311 }
312
313 /*! Gets the TeamSpeak server.
314 * \return TeamSpeak server.
315 * \sa TSServer
316 */
317 TSServer *GetServer() const
318 {
319 return m_pServer;
320 }
321
322 /*! Gets the TeamSpeak connection.
323 * \return TeamSpeak connection.
324 * \sa TSConnection
325 */
326 TSConnectionThread *GetConnection() const
327 {
328 return m_pConnection;
329 }
330
331 /*! Gets the session id.
332 * \return Session id.
333 */
334 wxUint32 GetSessionId() const
335 {
336 return m_SessionId;
337 }
338
339 /*! Gets Sync object, for thread sync
340 * \return Sync object.
341 */
342 TSCmd *GetSync() const
343 {
344 return m_pSync;
345 }
346
347 /*! Send a command to a Teasmpeak server.
348 * \param cmd Command to send.
349 * \return Returns false if fails, check GetLastError for details.
350 * \sa GetLastError() TSCommand for commands
351 */
352 bool SendCommand(wxUint32 cmd);
353
354 /*! Send a command to a Teasmpeak server.
355 * \param cmd Command to send.
356 * \return Returns false if fails, check GetLastError for details.
357 * \sa GetLastError() TSCommand for commands
358 */
359 bool SendCommand(TSCmd *cmd);
360
361 /*! Finds a player
362 * \param id Player id.
363 * \return Returns NULL if fails, check GetLastError for details.
364 * \sa GetLastError()
365 */
366 TSPlayer *FindPlayer(wxUint32 id);
367
368 /*! Finds a player
369 * \param str Player nick.
370 * \return Returns NULL if fails, check GetLastError for details.
371 * \sa GetLastError()
372 */
373 TSPlayer *FindPlayer(wxString const &str);
374
375 /*! Finds a channel
376 * \param id Channel id.
377 * \return Returns NULL if fails, check GetLastError for details.
378 * \sa GetLastError()
379 */
380 TSChannel *FindChannel(wxUint32 id);
381
382 /*! Finds a channel
383 * \param id Channel id.
384 * \return Returns NULL if fails, check GetLastError for details.
385 * \sa GetLastError()
386 */
387 TSChannel *FindChannel(wxString const &str);
388
389 /*! Finds default channel
390 * \return Returns NULL if fails, check GetLastError for details.
391 * \sa GetLastError()
392 */
393 TSChannel *FindDefaultChannel();
394
395 /*! Finds all channel with this parent id.
396 * \param id Channel id.
397 * \param channels Channel array
398 * \sa TSpChannelArray
399 */
400 bool FindChannelsByParent(wxUint32 id, TSpChannelArray *channels);
401
402 /*! Finds all channels per name, regex.
403 * \param str Channel name.
404 * \param channels Channel array
405 * \sa TSpChannelArray
406 */
407 bool FindChannelsByName(wxString const &str, TSpChannelArray *channels);
408
409 /*! Finds all players per name, regex.
410 * \param str Player name.
411 * \param players Player array
412 * \sa TSpPlayerArray
413 */
414 bool FindPlayersByName(wxString const &str, TSpPlayerArray *players);
415
416 /*! Finds all players in channel.
417 * \param channel Channel.
418 * \param players Player array
419 * \sa TSpPlayerArray
420 */
421 bool FindPlayersByChannel(TSChannel *channel, TSpPlayerArray *players);
422
423 /*! Creates a channel.
424 * \param channel Channel object.
425 * \return Returns false if fails, check GetLastError for details.
426 * \sa GetLastError() TSChannel
427 */
428 bool CreateChannel(TSChannel *channel);
429
430 /*! Deletes a channel.
431 * \param channel Channel object.
432 * \return Returns false if fails, check GetLastError for details.
433 * \sa GetLastError() TSChannel
434 */
435 bool DeleteChannel(TSChannel *channel);
436
437 /*! Modify a channel.
438 * \param channel Channel object.
439 * \return Returns false if fails, check GetLastError for details.
440 * \sa GetLastError() TSChannel
441 */
442 bool ModifyChannel(TSChannel *channel);
443
444 /*! Moves a Player.
445 * \param player Player object.
446 * \return Returns false if fails, check GetLastError for details.
447 * \sa GetLastError() TSChannel
448 */
449 bool MovePlayer(TSPlayer *player);
450
451 /*! Kick a Player.
452 * \param player Player object.
453 * \param msg Kick message.
454 * \return Returns false if fails, check GetLastError for details.
455 * \sa GetLastError() TSChannel
456 */
457 bool KickPlayer(TSPlayer *player, wxString msg = _T(""));
458
459 /*! Dumps object.
460 * \param ostrm Stream to write.
461 */
462 void Dump(wxOutputStream &ostrm) const;
463
464 private:
465 //Sets the LastError message.
466 void SetLastError(wxString const &str)
467 {
468 m_LastError = str;
469 }
470
471 //Members
472 TSPlayer *m_pPlayer;
473 TSpPlayerArray *m_ppPlayers;
474 TSChannel *m_pChannel;
475 TSpChannelArray *m_ppChannels;
476 TSServer *m_pServer;
477 TSConnectionThread *m_pConnection;
478 wxString m_LastError;
479 wxString m_VersionNumber;
480 wxString m_Platform;
481 wxUint32 m_SessionId;
482 wxMutex *m_pMutex;
483 TSCmd *m_pSync;
484 bool m_pReconnectAct;
485 public:
486 bool m_Lock;
487};
488
489#endif
diff --git a/tsclient.sh b/tsclient.sh
new file mode 100755
index 0000000..7a24c8d
--- /dev/null
+++ b/tsclient.sh
@@ -0,0 +1,108 @@
1#!/bin/bash
2
3binary="tsclient"
4arguments=""
5cd "$(dirname $0)"
6#export LD_LIBRARY_PATH="../wxBase-2.8.12/lib:../wxxml2/lib"
7
8#-------------------------------------------------------------------------------
9
10CHILDS=()
11process_running()
12{
13 CHILDS=`pgrep -d" " -x ${binary}`
14 if [ ! -z "${CHILDS}" ]; then
15 return 1
16 fi
17 return 0
18}
19
20#-------------------------------------------------------------------------------
21
22start()
23{
24 local retval=0
25
26 process_running
27 local state=$?
28 if [ ${state} -eq 0 ]; then
29 retval=1
30 ./${binary} ${arguments}
31
32 sleep 1
33 process_running
34 state=$?
35 if [ ${state} -eq 1 ]; then
36 ${OUTPUT} && echo "Process started..."
37 retval=1
38 else
39 ${OUTPUT} && echo "Couldn't start the process"
40 fi
41 else
42 ${OUTPUT} && echo "Process already running"
43 fi
44
45 return ${retval}
46}
47
48#-------------------------------------------------------------------------------
49
50stop()
51{
52 local retval=0
53
54 process_running
55 local state=$?
56 if [ ${state} -eq 1 ]; then
57 pkill -TERM -x ${binary}
58
59 sleep 1
60 process_running
61 state=$?
62 if [ ${state} -eq 1 ]; then
63 pkill -9 -x ${binary}
64 fi
65
66 ${OUTPUT} && echo "Process stopped"
67 retval=1
68 else
69 ${OUTPUT} && echo "Process not running"
70 fi
71
72 return ${retval}
73}
74
75#-------------------------------------------------------------------------------
76
77RETVAL=0
78OUTPUT=true
79if [ ! -z "$2" -a "$2" = "quiet" ]; then
80 OUTPUT=false
81fi
82
83case "$1" in
84 start)
85 start
86 RETVAL=$?
87 ;;
88 stop)
89 stop
90 RETVAL=$?
91 ;;
92 restart)
93 stop
94 start
95 RETVAL=$?
96 ;;
97 status)
98 process_running
99 state=$?
100 if [ ${state} -eq 1 ]; then
101 ${OUTPUT} && echo "Process is running (${CHILDS})..."
102 else
103 ${OUTPUT} && echo "Process is stopped"
104 fi
105 ;;
106esac
107
108exit ${RETVAL}
diff --git a/tscommand.cpp b/tscommand.cpp
new file mode 100644
index 0000000..881ce70
--- /dev/null
+++ b/tscommand.cpp
@@ -0,0 +1,1519 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tscommand.h"
21#include "wxstreamex.h"
22#include "wxbufferex.h"
23#include "crc32.h"
24
25//Libraries
26#include <wx/tokenzr.h>
27#include <wx/memory.h>
28#include <wx/wfstream.h>
29#include <wx/sstream.h>
30
31IMPLEMENT_CLASS(TSCommand, wxObject)
32
33//class variable
34wxUint32 TSCommand::m_Cnt = 0;
35
36//------------------------------------------------------------------------------
37// Send User
38bool TSCmdSendLogin::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
39{
40 TSClient *client = cmd->client;
41 wxByte buf[1024];
42 wxUint32 len = 0;
43 wxMemoryOutputStream tmpstrm;
44 wxDataOutputStreamEx out(tmpstrm);
45
46 TSCommand::m_Cnt = 0;
47
48 out.Write32(m_Id);
49 out.Write32(0); //SessionId
50 out.Write32(0); //PlayerId
51 out.Write32(m_Cnt++); //Counter
52 out.Write32(0); //CRC
53 out.WriteFixedString(_T("TeamSpeak")); //TeamSpeak
54 out.WriteFixedString(client->GetPlatform()); //Platform
55
56 //Write version number
57 wxStringTokenizer tkz(client->GetVersionNumber(), _T("."));
58 if(tkz.CountTokens() != 4)
59 {
60 SetLastError(_T("invalid version number, check format"));
61 return false;
62 }
63
64 //some conversions
65 long i;
66 tkz.GetNextToken().ToLong(&i);
67 out.Write16(wxUint16(i));
68 tkz.GetNextToken().ToLong(&i);
69 out.Write16(wxUint16(i));
70 tkz.GetNextToken().ToLong(&i);
71 out.Write16(wxUint16(i));
72 tkz.GetNextToken().ToLong(&i);
73 out.Write16(wxUint16(i));
74
75 out.Write8(client->GetPlayer()->GetServerAssingnsNickname()); //Allow server assing nick
76
77 out.Write8(client->GetPlayer()->GetAnonymous()); //Anonymous login
78 out.WriteFixedString(client->GetPlayer()->GetLoginName()); //Login name
79 out.WriteFixedString(client->GetPlayer()->GetLoginPassword()); //Login password
80 out.WriteFixedString(client->GetPlayer()->GetNickname()); //Nickname
81
82 len = tmpstrm.CopyTo(buf, 1024);
83 CRC32 myCRC32;
84 myCRC32.update(buf, len);
85
86 tmpstrm.SeekO(16);
87 out.Write32(myCRC32.getUint32Value());
88 len = tmpstrm.CopyTo(buf, len);
89
90 ostrm.Write(buf, len);
91
92 //only for reducing warnings
93 wxUnusedVar(istrm);
94 return true;
95}
96
97//------------------------------------------------------------------------------
98// Recv Server
99bool TSCmdRecvServer::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
100{
101 TSClient *client = cmd->client;
102 wxString str;
103 wxUint32 crc = 0;
104 wxUint32 id;
105 wxDataInputStreamEx in(istrm);
106
107 //read id
108 if(in.Read32() != m_Id)
109 {
110 SetLastError(_T("invalid command"));
111 return false;
112 }
113
114 in.Read32(); //Session id
115 client->GetPlayer()->SetId(in.Read32()); //Player id
116 in.Read32(); //Packet count
117 crc = in.Read32(); //CRC
118 in.ReadFixedString(str);
119 client->GetServer()->SetServerMessage(str); //Server message
120 str.Clear();
121 in.ReadFixedString(str);
122 client->GetServer()->SetPlatform(str); //Platform string
123 str.Clear();
124 str.Append(wxString::Format(_T("%d."), in.Read16()));
125 str.Append(wxString::Format(_T("%d."), in.Read16()));
126 str.Append(wxString::Format(_T("%d."), in.Read16()));
127 str.Append(wxString::Format(_T("%d"), in.Read16()));
128 client->GetServer()->SetVersionNumber(str);
129 id = in.Read32();
130 if(id == 0xffffffff)
131 {
132 SetLastError(_T("Bad Login (name and/or password wrong)"));
133 return false;
134 }
135 if(id == 0xfffffff9)
136 {
137 SetLastError(_T("This user is already logged in on the server"));
138 return false;
139 }
140 if(id > 100)
141 {
142 SetLastError(_T("Undefined user login error, check user data/permission"));
143 return false;
144 }
145 client->GetServer()->SetId(id);
146
147 in.Read32(); //unknown
148 in.Read32(); //unknown
149 client->GetServer()->SetServerType(in.Read16()); // servertype
150
151 //more unknown data
152 for(int i = 0; i < 70; i++)
153 in.Read8();
154
155 client->SetSessionId(in.Read32()); //Session id
156 client->GetPlayer()->SetId(in.Read32()); //Player id
157 str.Clear();
158 in.ReadFixedString(str, 255);
159 client->GetServer()->SetWelcomeMessage(str); //Welcome message
160
161 //only for reducing warnings
162 wxUnusedVar(ostrm);
163 wxUnusedVar(crc);
164 return true;
165}
166
167//------------------------------------------------------------------------------
168// Send default channel
169bool TSCmdSendDefault::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
170{
171 TSClient *client = cmd->client;
172 wxByte buf[1024];
173 wxUint32 len = 0;
174 wxMemoryOutputStream tmpstrm;
175 wxDataOutputStreamEx out(tmpstrm);
176
177 out.Write32(m_Id);
178 out.Write32(client->GetSessionId()); //SessionId
179 out.Write32(client->GetPlayer()->GetId()); //PlayerId
180 out.Write32(m_Cnt++); //Counter
181 out.Write32(0); //unknown
182 out.Write32(0); //CRC
183 out.Write16(1);
184 out.WriteFixedString(client->GetPlayer()->GetDefaultChannel());
185 out.WriteFixedString(client->GetPlayer()->GetDefaultSubchannel());
186 out.WriteFixedString(client->GetPlayer()->GetDefaultChannelPassword());
187 out.Write32(0); //unknown
188
189 len = tmpstrm.CopyTo(buf, 1024);
190 CRC32 myCRC32;
191 myCRC32.update(buf, len);
192
193 tmpstrm.SeekO(20);
194 out.Write32(myCRC32.getUint32Value());
195 len = tmpstrm.CopyTo(buf, len);
196
197 ostrm.Write(buf, len);
198
199 //only for reducing warnings
200 wxUnusedVar(istrm);
201 return true;
202}
203
204//------------------------------------------------------------------------------
205// TSRecvChannel
206bool TSCmdRecvChannel::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
207{
208 TSClient *client = cmd->client;
209 wxString str;
210 wxUint32 crc = 0;
211 wxUint32 channels = 0;
212 TSChannel *chl = NULL;
213 wxDataInputStreamEx in(istrm);
214
215 //read id
216 if(in.Read32() != m_Id)
217 {
218 SetLastError(_T("invalid command"));
219 return false;
220 }
221
222 in.Read32(); //Session id
223 in.Read32(); //Player id
224 cmd->pktid = in.Read32(); //Packet count
225 in.Read32(); //read unknown
226 crc = in.Read32(); //CRC
227 channels = in.Read32(); //read channel count
228
229 for(size_t i = 0; i < channels; i++)
230 {
231 wxUint32 chlid = in.Read32();
232 chl = client->FindChannel(chlid);
233 if(chl == NULL)
234 {
235 chl = new TSChannel;
236 client->GetChannels()->Add(chl);
237 }
238
239 chl->SetId(chlid);
240 chl->SetFlags(in.Read16());
241 chl->SetCodec(in.Read16());
242 chl->SetParent(in.Read32());
243 chl->SetOrder(in.Read16());
244 chl->SetMaxUsers(in.Read16());
245 str.Clear();
246 in.ReadZeroString(str);
247 chl->SetName(str);
248 str.Clear();
249 in.ReadZeroString(str);
250 chl->SetTopic(str);
251 str.Clear();
252 in.ReadZeroString(str);
253 chl->SetDescription(str);
254 }
255
256 //only for reducing warnings
257 wxUnusedVar(ostrm);
258 wxUnusedVar(crc);
259 return true;
260}
261
262//------------------------------------------------------------------------------
263// TSRecvUser
264bool TSCmdRecvUser::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
265{
266 TSClient *client = cmd->client;
267 wxString str;
268 wxUint32 crc = 0;
269 wxUint32 players = 0;
270 TSPlayer *ply = NULL;
271 wxDataInputStreamEx in(istrm);
272
273 //read id
274 if(in.Read32() != m_Id)
275 {
276 SetLastError(_T("invalid command"));
277 return false;
278 }
279
280 in.Read32(); //Session id
281 in.Read32(); //Player id
282 cmd->pktid = in.Read32(); //Packet count
283 in.Read32(); //read unknown
284 crc = in.Read32(); //CRC
285 players = in.Read32();
286
287 for(size_t i = 0; i < players; i++)
288 {
289 wxUint32 plyid = in.Read32();
290 ply = client->FindPlayer(plyid);
291 if(ply == NULL)
292 {
293 ply = new TSPlayer;
294 client->GetPlayers()->Add(ply);
295 }
296
297 ply->SetId(plyid);
298 ply->SetChannelId(in.Read32());
299 ply->SetChannelPrivileges(in.Read16());
300 ply->SetPrivileges(in.Read16());
301 ply->SetFlags(in.Read16());
302 str.Clear();
303 in.ReadFixedString(str);
304 ply->SetNickname(str);
305 }
306
307 //only for reducing warnings
308 wxUnusedVar(ostrm);
309 wxUnusedVar(crc);
310 return true;
311}
312
313//------------------------------------------------------------------------------
314// TSRecvAck
315bool TSCmdRecvAck::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
316{
317 wxUint32 crc = 0;
318 wxDataInputStreamEx in(istrm);
319
320 //read id
321 if(in.Read32() != m_Id)
322 {
323 SetLastError(_T("invalid command"));
324 return false;
325 }
326
327 in.Read32(); //Session id
328 in.Read32(); //Player id
329 cmd->pktid = in.Read32(); //Packet count
330 crc = in.Read32(); //CRC
331
332 //only for reducing warnings
333 wxUnusedVar(ostrm);
334 wxUnusedVar(crc);
335 return true;
336}
337
338
339//------------------------------------------------------------------------------
340// TSSendAck
341
342bool TSCmdSendAck::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
343{
344 TSClient *client = cmd->client;
345 wxByte buf[1024];
346 wxUint32 len = 0;
347 wxMemoryOutputStream tmpstrm;
348 wxDataOutputStreamEx out(tmpstrm);
349
350 out.Write32(TS_CMD_RECV_ACK); //same id as recv
351 out.Write32(client->GetSessionId()); //SessionId
352 out.Write32(client->GetPlayer()->GetId()); //PlayerId
353 out.Write32(cmd->pktid); //Counter
354 len = tmpstrm.CopyTo(buf, 1024);
355 ostrm.Write(buf, len);
356
357 //only for reducing warnings
358 wxUnusedVar(istrm);
359 return true;
360}
361
362//------------------------------------------------------------------------------
363// TSRecvUrl
364bool TSCmdRecvUrl::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
365{
366 wxUint32 crc = 0;
367 wxDataInputStreamEx in(istrm);
368
369 //read id
370 if(in.Read32() != m_Id)
371 {
372 SetLastError(_T("invalid command"));
373 return false;
374 }
375
376 in.Read32(); //Session id
377 in.Read32(); //Player id
378 cmd->pktid = in.Read32(); //Packet count
379 crc = in.Read32(); //CRC
380
381 //only for reducing warnings
382 wxUnusedVar(ostrm);
383 wxUnusedVar(crc);
384 return true;
385}
386
387//------------------------------------------------------------------------------
388// TSSendPing
389bool TSCmdSendPing::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
390{
391 TSClient *client = cmd->client;
392 wxByte buf[1024];
393 wxUint32 len = 0;
394 static wxUint32 cnt = 2;
395 wxMemoryOutputStream tmpstrm;
396 wxDataOutputStreamEx out(tmpstrm);
397
398 out.Write32(m_Id);
399 out.Write32(client->GetSessionId()); //SessionId
400 out.Write32(client->GetPlayer()->GetId()); //PlayerId
401 out.Write32(cnt++); //Counter
402 out.Write32(0);
403
404 len = tmpstrm.CopyTo(buf, 1024);
405 CRC32 myCRC32;
406 myCRC32.update(buf, len);
407
408 tmpstrm.SeekO(16);
409 out.Write32(myCRC32.getUint32Value());
410 len = tmpstrm.CopyTo(buf, len);
411
412 ostrm.Write(buf, len);
413
414 //only for reducing warnings
415 wxUnusedVar(istrm);
416 return true;
417}
418
419//------------------------------------------------------------------------------
420// TSRecvPing
421bool TSCmdRecvPing::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
422{
423 //only for reducing warnings
424 wxUnusedVar(istrm);
425 wxUnusedVar(ostrm);
426 wxUnusedVar(cmd);
427 return true;
428}
429
430//------------------------------------------------------------------------------
431// SendLogout
432bool TSCmdSendLogout::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
433{
434 TSClient *client = cmd->client;
435 wxByte buf[1024];
436 wxUint32 len = 0;
437 wxMemoryOutputStream tmpstrm;
438 wxDataOutputStreamEx out(tmpstrm);
439
440 out.Write32(m_Id);
441 out.Write32(client->GetSessionId()); //SessionId
442 out.Write32(client->GetPlayer()->GetId()); //PlayerId
443 out.Write32(m_Cnt++); //Counter
444 out.Write32(0);
445 out.Write32(0);
446
447 len = tmpstrm.CopyTo(buf, 1024);
448 CRC32 myCRC32;
449 myCRC32.update(buf, len);
450
451 tmpstrm.SeekO(20);
452 out.Write32(myCRC32.getUint32Value());
453 len = tmpstrm.CopyTo(buf, len);
454
455 ostrm.Write(buf, len);
456
457 //only for reducing warnings
458 wxUnusedVar(istrm);
459 return true;
460}
461
462//------------------------------------------------------------------------------
463// RecvLogoutInfo
464bool TSCmdRecvLogout::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
465{
466 TSClient *client = cmd->client;
467 wxUint32 crc = 0;
468 wxUint32 id;
469 wxDataInputStreamEx in(istrm);
470
471 //read id
472 if(in.Read32() != m_Id)
473 {
474 SetLastError(_T("invalid command"));
475 return false;
476 }
477
478 in.Read32(); //Session id
479 in.Read32(); //Player id
480 cmd->pktid = in.Read32(); //Packet count
481 in.Read32();
482 crc = in.Read32(); //CRC
483 id = in.Read32();
484
485 for(size_t i = 0; i < client->GetPlayers()->GetCount(); i++)
486 {
487 if(id == client->GetPlayers()->Item(i)->GetId())
488 {
489 delete client->GetPlayers()->Item(i);
490 client->GetPlayers()->RemoveAt(i);
491 return true;
492 }
493 }
494
495 //only for reducing warnings
496 wxUnusedVar(ostrm);
497 wxUnusedVar(crc);
498
499 SetLastError(_T("unknown player, not found in list, can't remove"));
500 return false;
501}
502
503//------------------------------------------------------------------------------
504// TSCmdRecvAddPlayer
505bool TSCmdRecvAddPlayer::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
506{
507 TSClient *client = cmd->client;
508 wxString str;
509 wxUint32 crc = 0;
510 wxUint32 id = 0;
511 TSPlayer *ply = NULL;
512 wxDataInputStreamEx in(istrm);
513
514 //read id
515 if(in.Read32() != m_Id)
516 {
517 SetLastError(_T("invalid command"));
518 return false;
519 }
520
521 in.Read32(); //Session id
522 in.Read32(); //Player id
523 cmd->pktid = in.Read32(); //Packet count
524 in.Read32(); //read unknown
525 crc = in.Read32(); //CRC
526 id = in.Read32(); //Player id
527 ply = client->FindPlayer(id);
528
529 if(ply == NULL)
530 {
531 ply = new TSPlayer;
532 client->GetPlayers()->Add(ply);
533 }
534
535 ply->SetId(id);
536 ply->SetChannelId(in.Read32());
537 ply->SetChannelPrivileges(in.Read16());
538 ply->SetPrivileges(in.Read16());
539 ply->SetFlags(in.Read16());
540 str.Clear();
541 in.ReadFixedString(str);
542 ply->SetNickname(str);
543
544 //only for reducing warnings
545 wxUnusedVar(ostrm);
546 wxUnusedVar(crc);
547 return true;
548}
549
550//------------------------------------------------------------------------------
551// TSCmdRecvPlayerFlags
552bool TSCmdRecvPlayerFlags::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
553{
554 TSClient *client = cmd->client;
555 TSPlayer *ply = NULL;
556 wxUint32 crc = 0;
557 wxUint32 plyid = 0;
558 wxUint32 plyflags = 0;
559 wxDataInputStreamEx in(istrm);
560
561 //read id
562 if(in.Read32() != m_Id)
563 {
564 SetLastError(_T("invalid command"));
565 return false;
566 }
567
568 in.Read32(); //Session id
569 in.Read32(); //Player id
570 cmd->pktid = in.Read32(); //Packet count
571 in.Read32(); //read unknown
572 crc = in.Read32(); //CRC
573 plyid = in.Read32();
574 plyflags = in.Read16();
575
576 ply = client->FindPlayer(plyid);
577 if(ply != NULL)
578 {
579 ply->SetFlags(plyflags);
580 return true;
581 }
582
583 //only for reducing warnings
584 wxUnusedVar(ostrm);
585 wxUnusedVar(crc);
586
587 SetLastError(_T("unknown player, not found in list, flags not set"));
588 return false;
589}
590
591//------------------------------------------------------------------------------
592// TSCmdRecvAddChannel
593bool TSCmdRecvAddChannel::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
594{
595 TSClient *client = cmd->client;
596 TSChannel *chl = NULL;
597 wxString str;
598 wxUint32 crc = 0;
599 wxUint32 chlid = 0;
600 wxDataInputStreamEx in(istrm);
601
602 //read id
603 if(in.Read32() != m_Id)
604 {
605 SetLastError(_T("invalid command"));
606 return false;
607 }
608
609 in.Read32(); //Session id
610 in.Read32(); //Player id
611 cmd->pktid = in.Read32(); //Packet count
612 in.Read32(); //read unknown
613 crc = in.Read32(); //CRC
614 in.Read32(); //user
615 chlid = in.Read32();
616 chl = client->FindChannel(chlid);
617 if(chl == NULL)
618 {
619 chl = new TSChannel;
620 client->GetChannels()->Add(chl);
621 }
622
623 chl->SetId(chlid);
624 chl->SetFlags(in.Read16());
625 chl->SetCodec(in.Read16());
626 chl->SetParent(in.Read32());
627 chl->SetOrder(in.Read16());
628 chl->SetMaxUsers(in.Read16());
629 str.Clear();
630 in.ReadZeroString(str);
631 chl->SetName(str);
632 str.Clear();
633 in.ReadZeroString(str);
634 chl->SetTopic(str);
635 str.Clear();
636 in.ReadZeroString(str);
637 chl->SetDescription(str);
638
639 //only for reducing warnings
640 wxUnusedVar(ostrm);
641 wxUnusedVar(crc);
642 return true;
643}
644
645//------------------------------------------------------------------------------
646// TSCmdRecvMovePlayer
647bool TSCmdRecvMovePlayer::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
648{
649 TSClient *client = cmd->client;
650 TSPlayer *ply = NULL;
651 wxUint32 crc = 0;
652 wxUint32 plyid = 0;
653 wxUint32 chlid = 0;
654 wxDataInputStreamEx in(istrm);
655
656 //read id
657 if(in.Read32() != m_Id)
658 {
659 SetLastError(_T("invalid command"));
660 return false;
661 }
662
663 in.Read32(); //Session id
664 in.Read32(); //Player id
665 cmd->pktid = in.Read32(); //Packet count
666 in.Read32(); //read unknown
667 crc = in.Read32(); //CRC
668 plyid = in.Read32();
669 in.Read32(); //old channel
670 chlid = in.Read32(); //new channel
671 in.Read16(); //unknown
672
673 ply = client->FindPlayer(plyid);
674 if(ply != NULL)
675 {
676 ply->SetChannelId(chlid);
677 return true;
678 }
679
680 //only for reducing warnings
681 wxUnusedVar(ostrm);
682 wxUnusedVar(crc);
683
684 SetLastError(_T("unknown player, not found in list, channel not set"));
685 return false;
686}
687
688//------------------------------------------------------------------------------
689// TSCmdRecvMovePlayer
690bool TSCmdRecvMovePlayer2::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
691{
692 TSClient *client = cmd->client;
693 TSPlayer *ply = NULL;
694 wxUint32 crc = 0;
695 wxUint32 plyid = 0;
696 wxUint32 chlid = 0;
697 wxDataInputStreamEx in(istrm);
698
699 //read id
700 if(in.Read32() != m_Id)
701 {
702 SetLastError(_T("invalid command"));
703 return false;
704 }
705
706 in.Read32(); //Session id
707 in.Read32(); //Player id
708 cmd->pktid = in.Read32(); //Packet count
709 in.Read32(); //read unknown
710 crc = in.Read32(); //CRC
711 plyid = in.Read32();
712 in.Read32(); //old channel
713 chlid = in.Read32(); //new channel
714 in.Read16(); //unknown
715
716 ply = client->FindPlayer(plyid);
717 if(ply != NULL)
718 {
719 ply->SetChannelId(chlid);
720 return true;
721 }
722
723 //only for reducing warnings
724 wxUnusedVar(ostrm);
725 wxUnusedVar(crc);
726
727 SetLastError(_T("unknown player, not found in list, channel not set"));
728 return false;
729}
730
731//------------------------------------------------------------------------------
732// TSCmdRecvDelChannel
733bool TSCmdRecvDelChannel::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
734{
735 TSClient *client = cmd->client;
736 wxUint32 crc = 0;
737 wxUint32 plyid = 0;
738 wxUint16 chlid = 0;
739 wxDataInputStreamEx in(istrm);
740
741 //read id
742 if(in.Read32() != m_Id)
743 {
744 SetLastError(_T("invalid command"));
745 return false;
746 }
747
748 in.Read32(); //Session id
749 in.Read32(); //Player id
750 cmd->pktid = in.Read32(); //Packet count
751 in.Read32(); //read unknown
752 crc = in.Read32(); //CRC
753 chlid = in.Read16(); // channel
754 plyid = in.Read32();
755
756 for(size_t i = 0; i < client->GetChannels()->GetCount(); i++)
757 {
758 if(chlid == client->GetChannels()->Item(i)->GetId())
759 {
760 delete client->GetChannels()->Item(i);
761 client->GetChannels()->RemoveAt(i);
762 return true;
763 }
764 }
765
766 //only for reducing warnings
767 wxUnusedVar(ostrm);
768 wxUnusedVar(crc);
769 wxUnusedVar(plyid);
770
771 SetLastError(_T("unknown channel, not found in list"));
772 return false;
773}
774
775//------------------------------------------------------------------------------
776// TSCmdRecvServerUpdate
777bool TSCmdRecvServerUpdate::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
778{
779 wxUint32 crc = 0;
780 wxDataInputStreamEx in(istrm);
781
782 //read id
783 if(in.Read32() != m_Id)
784 {
785 SetLastError(_T("invalid command"));
786 return false;
787 }
788
789 in.Read32(); //Session id
790 in.Read32(); //Player id
791 cmd->pktid = in.Read32(); //Packet count
792 in.Read32(); //read unknown
793 crc = in.Read32(); //CRC
794
795 // in.Read32(); //unknown
796 // in.Read32(); //unknown
797 // servertype = in.Read16(); //clan=05, public=06
798 // more unknown data
799 // all over 80 byte (so 62 left or so)
800
801 //only for reducing warnings
802 wxUnusedVar(ostrm);
803 wxUnusedVar(crc);
804
805 return true;
806}
807
808//------------------------------------------------------------------------------
809// TSCmdSendAddChannel
810bool TSCmdSendAddChannel::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
811{
812 TSClient *client = cmd->client;
813 wxByte buf[1024];
814 wxUint32 len = 0;
815 wxMemoryOutputStream tmpstrm;
816 wxDataOutputStreamEx out(tmpstrm);
817
818 out.Write32(m_Id);
819 out.Write32(client->GetSessionId()); //SessionId
820 out.Write32(client->GetPlayer()->GetId()); //PlayerId
821 out.Write32(m_Cnt++); //Counter
822 out.Write32(0); //unknown
823 out.Write32(0); //crc
824
825 out.Write32(0); //must be null
826
827 out.Write16(cmd->param1.pChannel->GetFlags());
828 out.Write16(cmd->param1.pChannel->GetCodec());
829 out.Write32(cmd->param1.pChannel->GetParent());
830 out.Write16(cmd->param1.pChannel->GetOrder());
831 out.Write16(cmd->param1.pChannel->GetMaxUsers());
832 out.WriteZeroString(cmd->param1.pChannel->GetName());
833 out.WriteZeroString(cmd->param1.pChannel->GetTopic());
834 out.WriteZeroString(cmd->param1.pChannel->GetDescription());
835 if (cmd->param1.pChannel->GetPassword().Length() > 0)
836 out.WriteZeroString(cmd->param1.pChannel->GetPassword());
837 else
838 out.Write8(0);
839
840 len = tmpstrm.CopyTo(buf, 1024);
841 CRC32 myCRC32;
842 myCRC32.update(buf, len);
843
844 tmpstrm.SeekO(20);
845 out.Write32(myCRC32.getUint32Value());
846 len = tmpstrm.CopyTo(buf, len);
847
848 ostrm.Write(buf, len);
849
850 //only for reducing warnings
851 wxUnusedVar(istrm);
852 return true;
853}
854
855//------------------------------------------------------------------------------
856// TSCmdSendDelChannel
857bool TSCmdSendDelChannel::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
858{
859 TSClient *client = cmd->client;
860 wxByte buf[1024];
861 wxUint32 len = 0;
862 wxMemoryOutputStream tmpstrm;
863 wxDataOutputStreamEx out(tmpstrm);
864
865 out.Write32(m_Id);
866 out.Write32(client->GetSessionId()); //SessionId
867 out.Write32(client->GetPlayer()->GetId()); //PlayerId
868 out.Write32(m_Cnt++); //Counter
869 out.Write32(0); //unknown
870 out.Write32(0); //crc
871
872 out.Write32(cmd->param1.pChannel->GetId());
873
874 len = tmpstrm.CopyTo(buf, 1024);
875 CRC32 myCRC32;
876 myCRC32.update(buf, len);
877
878 tmpstrm.SeekO(20);
879 out.Write32(myCRC32.getUint32Value());
880 len = tmpstrm.CopyTo(buf, len);
881
882 ostrm.Write(buf, len);
883
884 //only for reducing warnings
885 wxUnusedVar(istrm);
886 return true;
887}
888
889//------------------------------------------------------------------------------
890// TSCmdSendMovePlayer
891bool TSCmdSendMovePlayer::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
892{
893 TSClient *client = cmd->client;
894 wxByte buf[1024];
895 wxUint32 len = 0;
896 wxMemoryOutputStream tmpstrm;
897 wxDataOutputStreamEx out(tmpstrm);
898
899 out.Write32(m_Id);
900 out.Write32(client->GetSessionId()); //SessionId
901 out.Write32(client->GetPlayer()->GetId()); //PlayerId
902 out.Write32(m_Cnt++); //Counter
903 out.Write32(0); //unknown
904 out.Write32(0); //crc
905
906 out.Write32(cmd->param1.pPlayer->GetId());
907 out.Write32(cmd->param1.pPlayer->GetChannelId());
908
909 len = tmpstrm.CopyTo(buf, 1024);
910 CRC32 myCRC32;
911 myCRC32.update(buf, len);
912
913 tmpstrm.SeekO(20);
914 out.Write32(myCRC32.getUint32Value());
915 len = tmpstrm.CopyTo(buf, len);
916
917 ostrm.Write(buf, len);
918
919 //only for reducing warnings
920 wxUnusedVar(istrm);
921 return true;
922}
923
924//------------------------------------------------------------------------------
925// TSCmdSendSetChannelPassword
926bool TSCmdSendSetChannelPassword::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
927{
928 TSClient *client = cmd->client;
929 wxByte buf[1024];
930 wxUint32 len = 0;
931 wxMemoryOutputStream tmpstrm;
932 wxDataOutputStreamEx out(tmpstrm);
933
934 out.Write32(m_Id);
935 out.Write32(client->GetSessionId()); //SessionId
936 out.Write32(client->GetPlayer()->GetId()); //PlayerId
937 out.Write32(m_Cnt++); //Counter
938 out.Write32(0); //unknown
939 out.Write32(0); //crc
940
941 out.Write32(cmd->param1.pChannel->GetId());
942 out.WriteFixedString(cmd->param1.pChannel->GetPassword());
943
944 len = tmpstrm.CopyTo(buf, 1024);
945 CRC32 myCRC32;
946 myCRC32.update(buf, len);
947
948 tmpstrm.SeekO(20);
949 out.Write32(myCRC32.getUint32Value());
950 len = tmpstrm.CopyTo(buf, len);
951
952 ostrm.Write(buf, len);
953
954 //only for reducing warnings
955 wxUnusedVar(istrm);
956 return true;
957}
958
959//------------------------------------------------------------------------------
960// TSCmdSendSetChannelName
961bool TSCmdSendSetChannelName::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
962{
963 TSClient *client = cmd->client;
964 wxByte buf[1024];
965 wxUint32 len = 0;
966 wxMemoryOutputStream tmpstrm;
967 wxDataOutputStreamEx out(tmpstrm);
968
969 out.Write32(m_Id);
970 out.Write32(client->GetSessionId()); //SessionId
971 out.Write32(client->GetPlayer()->GetId()); //PlayerId
972 out.Write32(m_Cnt++); //Counter
973 out.Write32(0); //unknown
974 out.Write32(0); //crc
975
976 out.Write32(cmd->param1.pChannel->GetId());
977 out.WriteZeroString(cmd->param1.pChannel->GetName());
978
979 len = tmpstrm.CopyTo(buf, 1024);
980 CRC32 myCRC32;
981 myCRC32.update(buf, len);
982
983 tmpstrm.SeekO(20);
984 out.Write32(myCRC32.getUint32Value());
985 len = tmpstrm.CopyTo(buf, len);
986
987 ostrm.Write(buf, len);
988
989 //only for reducing warnings
990 wxUnusedVar(istrm);
991 wxUnusedVar(ostrm);
992 return true;
993}
994
995//------------------------------------------------------------------------------
996// TSCmdSendSetChannelTopic
997bool TSCmdSendSetChannelTopic::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
998{
999 TSClient *client = cmd->client;
1000 wxByte buf[1024];
1001 wxUint32 len = 0;
1002 wxMemoryOutputStream tmpstrm;
1003 wxDataOutputStreamEx out(tmpstrm);
1004
1005 out.Write32(m_Id);
1006 out.Write32(client->GetSessionId()); //SessionId
1007 out.Write32(client->GetPlayer()->GetId()); //PlayerId
1008 out.Write32(m_Cnt++); //Counter
1009 out.Write32(0); //unknown
1010 out.Write32(0); //crc
1011
1012 out.Write32(cmd->param1.pChannel->GetId());
1013 out.WriteZeroString(cmd->param1.pChannel->GetTopic());
1014
1015 len = tmpstrm.CopyTo(buf, 1024);
1016 CRC32 myCRC32;
1017 myCRC32.update(buf, len);
1018
1019 tmpstrm.SeekO(20);
1020 out.Write32(myCRC32.getUint32Value());
1021 len = tmpstrm.CopyTo(buf, len);
1022
1023 ostrm.Write(buf, len);
1024
1025 //only for reducing warnings
1026 wxUnusedVar(istrm);
1027 return true;
1028}
1029
1030//------------------------------------------------------------------------------
1031// TSCmdSendSetChannelDescription
1032bool TSCmdSendSetChannelDescription::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1033{
1034 TSClient *client = cmd->client;
1035 wxByte buf[1024];
1036 wxUint32 len = 0;
1037 wxMemoryOutputStream tmpstrm;
1038 wxDataOutputStreamEx out(tmpstrm);
1039
1040 out.Write32(m_Id);
1041 out.Write32(client->GetSessionId()); //SessionId
1042 out.Write32(client->GetPlayer()->GetId()); //PlayerId
1043 out.Write32(m_Cnt++); //Counter
1044 out.Write32(0); //unknown
1045 out.Write32(0); //crc
1046
1047 out.Write32(cmd->param1.pChannel->GetId());
1048 out.WriteZeroString(cmd->param1.pChannel->GetDescription());
1049
1050 len = tmpstrm.CopyTo(buf, 1024);
1051 CRC32 myCRC32;
1052 myCRC32.update(buf, len);
1053
1054 tmpstrm.SeekO(20);
1055 out.Write32(myCRC32.getUint32Value());
1056 len = tmpstrm.CopyTo(buf, len);
1057
1058 ostrm.Write(buf, len);
1059
1060 //only for reducing warnings
1061 wxUnusedVar(istrm);
1062 return true;
1063}
1064
1065//------------------------------------------------------------------------------
1066// TSCmdSendSetChannelMaxPlayers
1067bool TSCmdSendSetChannelMaxPlayers::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1068{
1069 TSClient *client = cmd->client;
1070 wxByte buf[1024];
1071 wxUint32 len = 0;
1072 wxMemoryOutputStream tmpstrm;
1073 wxDataOutputStreamEx out(tmpstrm);
1074
1075 out.Write32(m_Id);
1076 out.Write32(client->GetSessionId()); //SessionId
1077 out.Write32(client->GetPlayer()->GetId()); //PlayerId
1078 out.Write32(m_Cnt++); //Counter
1079 out.Write32(0); //unknown
1080 out.Write32(0); //crc
1081
1082 out.Write32(cmd->param1.pChannel->GetId());
1083 out.Write16(cmd->param1.pChannel->GetMaxUsers());
1084
1085 len = tmpstrm.CopyTo(buf, 1024);
1086 CRC32 myCRC32;
1087 myCRC32.update(buf, len);
1088
1089 tmpstrm.SeekO(20);
1090 out.Write32(myCRC32.getUint32Value());
1091 len = tmpstrm.CopyTo(buf, len);
1092
1093 ostrm.Write(buf, len);
1094
1095 //only for reducing warnings
1096 wxUnusedVar(istrm);
1097 wxUnusedVar(ostrm);
1098 return true;
1099}
1100
1101//------------------------------------------------------------------------------
1102// TSCmdSendSetChannelFlagsCodec
1103bool TSCmdSendSetChannelFlagsCodec::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1104{
1105 TSClient *client = cmd->client;
1106 wxByte buf[1024];
1107 wxUint32 len = 0;
1108 wxMemoryOutputStream tmpstrm;
1109 wxDataOutputStreamEx out(tmpstrm);
1110
1111 out.Write32(m_Id);
1112 out.Write32(client->GetSessionId()); //SessionId
1113 out.Write32(client->GetPlayer()->GetId()); //PlayerId
1114 out.Write32(m_Cnt++); //Counter
1115 out.Write32(0); //unknown
1116 out.Write32(0); //crc
1117
1118 out.Write32(cmd->param1.pChannel->GetId());
1119 out.Write16(cmd->param1.pChannel->GetFlags());
1120 out.Write16(cmd->param1.pChannel->GetCodec());
1121
1122 len = tmpstrm.CopyTo(buf, 1024);
1123 CRC32 myCRC32;
1124 myCRC32.update(buf, len);
1125
1126 tmpstrm.SeekO(20);
1127 out.Write32(myCRC32.getUint32Value());
1128 len = tmpstrm.CopyTo(buf, len);
1129
1130 ostrm.Write(buf, len);
1131
1132 //only for reducing warnings
1133 wxUnusedVar(istrm);
1134 return true;
1135}
1136
1137//------------------------------------------------------------------------------
1138// TSCmdSendSetChannelOrder
1139bool TSCmdSendSetChannelOrder::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1140{
1141 TSClient *client = cmd->client;
1142 wxByte buf[1024];
1143 wxUint32 len = 0;
1144 wxMemoryOutputStream tmpstrm;
1145 wxDataOutputStreamEx out(tmpstrm);
1146
1147 out.Write32(m_Id);
1148 out.Write32(client->GetSessionId()); //SessionId
1149 out.Write32(client->GetPlayer()->GetId()); //PlayerId
1150 out.Write32(m_Cnt++); //Counter
1151 out.Write32(0); //unknown
1152 out.Write32(0); //crc
1153
1154 out.Write32(cmd->param1.pChannel->GetId());
1155 out.Write16(cmd->param1.pChannel->GetOrder());
1156
1157 len = tmpstrm.CopyTo(buf, 1024);
1158 CRC32 myCRC32;
1159 myCRC32.update(buf, len);
1160
1161 tmpstrm.SeekO(20);
1162 out.Write32(myCRC32.getUint32Value());
1163 len = tmpstrm.CopyTo(buf, len);
1164
1165 ostrm.Write(buf, len);
1166
1167 //only for reducing warnings
1168 wxUnusedVar(istrm);
1169 return true;
1170}
1171
1172//------------------------------------------------------------------------------
1173// TSCmdRecvSetChannelName
1174bool TSCmdRecvSetChannelName::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1175{
1176 TSClient *client = cmd->client;
1177 TSChannel *chl = NULL;
1178 wxString str;
1179 wxUint32 crc = 0;
1180 wxUint32 chlid = 0;
1181 wxDataInputStreamEx in(istrm);
1182
1183 //read id
1184 if(in.Read32() != m_Id)
1185 {
1186 SetLastError(_T("invalid command"));
1187 return false;
1188 }
1189
1190 in.Read32(); //Session id
1191 in.Read32(); //Player id
1192 cmd->pktid = in.Read32(); //Packet count
1193 in.Read32(); //read unknown
1194 crc = in.Read32(); //CRC
1195 chlid = in.Read32();
1196
1197 chl = client->FindChannel(chlid);
1198 if(chl == NULL)
1199 {
1200 SetLastError(_T("can't find channel"));
1201 return false;
1202 }
1203
1204 in.Read32(); //user id
1205
1206 str.Clear();
1207 in.ReadZeroString(str);
1208 chl->SetName(str);
1209
1210 //only for reducing warnings
1211 wxUnusedVar(ostrm);
1212 wxUnusedVar(crc);
1213 return true;
1214}
1215
1216//------------------------------------------------------------------------------
1217// TSCmdRecvSetChannelTopic
1218bool TSCmdRecvSetChannelTopic::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1219{
1220 TSClient *client = cmd->client;
1221 TSChannel *chl = NULL;
1222 wxString str;
1223 wxUint32 crc = 0;
1224 wxUint32 chlid = 0;
1225 wxDataInputStreamEx in(istrm);
1226
1227 //read id
1228 if(in.Read32() != m_Id)
1229 {
1230 SetLastError(_T("invalid command"));
1231 return false;
1232 }
1233
1234 in.Read32(); //Session id
1235 in.Read32(); //Player id
1236 cmd->pktid = in.Read32(); //Packet count
1237 in.Read32(); //read unknown
1238 crc = in.Read32(); //CRC
1239 chlid = in.Read32();
1240
1241 chl = client->FindChannel(chlid);
1242 if(chl == NULL)
1243 {
1244 SetLastError(_T("can't find channel"));
1245 return false;
1246 }
1247
1248 in.Read32(); //user id
1249
1250 str.Clear();
1251 in.ReadZeroString(str);
1252 chl->SetTopic(str);
1253
1254 //only for reducing warnings
1255 wxUnusedVar(ostrm);
1256 wxUnusedVar(crc);
1257 return true;
1258}
1259
1260//------------------------------------------------------------------------------
1261// TSCmdRecvSetChannelDescription
1262bool TSCmdRecvSetChannelDescription::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1263{
1264 TSClient *client = cmd->client;
1265 TSChannel *chl = NULL;
1266 wxString str;
1267 wxUint32 crc = 0;
1268 wxUint32 chlid = 0;
1269 wxDataInputStreamEx in(istrm);
1270
1271 //read id
1272 if(in.Read32() != m_Id)
1273 {
1274 SetLastError(_T("invalid command"));
1275 return false;
1276 }
1277
1278 in.Read32(); //Session id
1279 in.Read32(); //Player id
1280 cmd->pktid = in.Read32(); //Packet count
1281 in.Read32(); //read unknown
1282 crc = in.Read32(); //CRC
1283 chlid = in.Read32();
1284
1285 chl = client->FindChannel(chlid);
1286 if(chl == NULL)
1287 {
1288 SetLastError(_T("can't find channel"));
1289 return false;
1290 }
1291
1292 in.Read32(); //user id
1293
1294 str.Clear();
1295 in.ReadZeroString(str);
1296 chl->SetDescription(str);
1297
1298 //only for reducing warnings
1299 wxUnusedVar(ostrm);
1300 wxUnusedVar(crc);
1301 return true;
1302}
1303
1304//------------------------------------------------------------------------------
1305// TSCmdRecvSetChannelMaxPlayers
1306bool TSCmdRecvSetChannelMaxPlayers::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1307{
1308 TSClient *client = cmd->client;
1309 TSChannel *chl = NULL;
1310 wxUint32 crc = 0;
1311 wxUint32 chlid = 0;
1312 wxDataInputStreamEx in(istrm);
1313
1314 //read id
1315 if(in.Read32() != m_Id)
1316 {
1317 SetLastError(_T("invalid command"));
1318 return false;
1319 }
1320
1321 in.Read32(); //Session id
1322 in.Read32(); //Player id
1323 cmd->pktid = in.Read32(); //Packet count
1324 in.Read32(); //read unknown
1325 crc = in.Read32(); //CRC
1326 chlid = in.Read32();
1327
1328 chl = client->FindChannel(chlid);
1329 if(chl == NULL)
1330 {
1331 SetLastError(_T("can't find channel"));
1332 return false;
1333 }
1334
1335 chl->SetMaxUsers(in.Read16());
1336
1337 //only for reducing warnings
1338 wxUnusedVar(ostrm);
1339 wxUnusedVar(crc);
1340 return true;
1341}
1342
1343//------------------------------------------------------------------------------
1344// TSCmdRecvSetChannelFlagsCodec
1345bool TSCmdRecvSetChannelFlagsCodec::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1346{
1347 TSClient *client = cmd->client;
1348 TSChannel *chl = NULL;
1349 wxUint32 crc = 0;
1350 wxUint32 chlid = 0;
1351 wxDataInputStreamEx in(istrm);
1352
1353 //read id
1354 if(in.Read32() != m_Id)
1355 {
1356 SetLastError(_T("invalid command"));
1357 return false;
1358 }
1359
1360 in.Read32(); //Session id
1361 in.Read32(); //Player id
1362 cmd->pktid = in.Read32(); //Packet count
1363 in.Read32(); //read unknown
1364 crc = in.Read32(); //CRC
1365 chlid = in.Read32();
1366
1367 chl = client->FindChannel(chlid);
1368 if(chl == NULL)
1369 {
1370 SetLastError(_T("can't find channel"));
1371 return false;
1372 }
1373
1374 chl->SetFlags(in.Read16());
1375 chl->SetCodec(in.Read16());
1376
1377 //only for reducing warnings
1378 wxUnusedVar(ostrm);
1379 wxUnusedVar(crc);
1380 return true;
1381}
1382
1383//------------------------------------------------------------------------------
1384// TSCmdRecvSetChannelOrder
1385bool TSCmdRecvSetChannelOrder::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1386{
1387 TSClient *client = cmd->client;
1388 TSChannel *chl = NULL;
1389 wxUint32 crc = 0;
1390 wxUint32 chlid = 0;
1391 wxDataInputStreamEx in(istrm);
1392
1393 //read id
1394 if(in.Read32() != m_Id)
1395 {
1396 SetLastError(_T("invalid command"));
1397 return false;
1398 }
1399
1400 in.Read32(); //Session id
1401 in.Read32(); //Player id
1402 cmd->pktid = in.Read32(); //Packet count
1403 in.Read32(); //read unknown
1404 crc = in.Read32(); //CRC
1405 chlid = in.Read32();
1406
1407 chl = client->FindChannel(chlid);
1408 if(chl == NULL)
1409 {
1410 SetLastError(_T("can't find channel"));
1411 return false;
1412 }
1413
1414 chl->SetOrder(in.Read32());
1415
1416 //only for reducing warnings
1417 wxUnusedVar(ostrm);
1418 wxUnusedVar(crc);
1419 return true;
1420}
1421
1422//------------------------------------------------------------------------------
1423// TSCmdSendKickPlayer
1424bool TSCmdSendKickPlayer::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1425{
1426 TSClient *client = cmd->client;
1427 wxByte buf[1024];
1428 wxUint32 len = 0;
1429 wxMemoryOutputStream tmpstrm;
1430 wxDataOutputStreamEx out(tmpstrm);
1431
1432 out.Write32(m_Id);
1433 out.Write32(client->GetSessionId()); //SessionId
1434 out.Write32(client->GetPlayer()->GetId()); //PlayerId
1435 out.Write32(m_Cnt++); //Counter
1436 out.Write32(0); //unknown
1437 out.Write32(0); //crc
1438
1439 out.Write32(cmd->param1.pPlayer->GetId());
1440 out.WriteFixedString(*cmd->param2.pString);
1441
1442
1443 len = tmpstrm.CopyTo(buf, 1024);
1444 CRC32 myCRC32;
1445 myCRC32.update(buf, len);
1446
1447 tmpstrm.SeekO(20);
1448 out.Write32(myCRC32.getUint32Value());
1449 len = tmpstrm.CopyTo(buf, len);
1450
1451 ostrm.Write(buf, len);
1452
1453 //only for reducing warnings
1454 wxUnusedVar(istrm);
1455 return true;
1456}
1457
1458//------------------------------------------------------------------------------
1459// TSCmdRecvChannelPasswordChanged
1460bool TSCmdRecvChannelPasswordChanged::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1461{
1462 wxUint32 crc = 0;
1463 wxDataInputStreamEx in(istrm);
1464
1465 //read id
1466 if(in.Read32() != m_Id)
1467 {
1468 SetLastError(_T("invalid command"));
1469 return false;
1470 }
1471
1472 in.Read32(); //Session id
1473 in.Read32(); //Player id
1474 cmd->pktid = in.Read32(); //Packet count
1475 in.Read32(); //read unknown
1476 crc = in.Read32(); //CRC
1477
1478 //do nothing
1479
1480 //only for reducing warnings
1481 wxUnusedVar(ostrm);
1482 wxUnusedVar(crc);
1483 return true;
1484}
1485
1486//------------------------------------------------------------------------------
1487// TSCmdRecvUnknown
1488bool TSCmdRecvUnknown::ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd)
1489{
1490 wxMemoryBufferEx buf(1024);
1491 wxUint32 cnt = 0;
1492
1493 while(!istrm.Eof())
1494 {
1495 cnt++;
1496 buf.AppendByte(istrm.GetC());
1497 }
1498 buf.SetDataLen(cnt);
1499 wxMemoryInputStream tmp(buf.GetData(), buf.GetDataLen());
1500 wxDataInputStreamEx in(tmp);
1501
1502 wxLogVerbose(_T("dumping unknown command..."));
1503
1504 wxLogVerbose(_T("Id: %#x"), in.Read32()); //read id
1505 wxLogVerbose(_T("SessionId: %#x"), in.Read32()); //Session id
1506 wxLogVerbose(_T("PlayerId: %#x"), in.Read32()); //Player id
1507
1508 cmd->pktid = in.Read32(); //Packet count
1509 wxLogVerbose(_T("PacketId: %#x"), cmd->pktid);
1510
1511 wxStringOutputStream so;
1512 buf.HexDump(so);
1513 wxLogVerbose(_T("Hex dump:\n%s"), so.GetString().c_str());
1514
1515 //only for reducing warnings
1516 wxUnusedVar(ostrm);
1517 return true;
1518}
1519
diff --git a/tscommand.h b/tscommand.h
new file mode 100644
index 0000000..d7774a2
--- /dev/null
+++ b/tscommand.h
@@ -0,0 +1,524 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef TSCOMMAND_H
20#define TSCOMMAND_H
21
22#include "tsheaders.h"
23
24#include <wx/wx.h>
25#include <wx/stream.h>
26#include <wx/datstrm.h>
27#include <wx/mstream.h>
28#include <wx/dynarray.h>
29
30//Commands
31#define TS_CMD_RECV_UNKNOWN 0xffffffff //!< Recv unknown command
32#define TS_CMD_SEND_LOGIN 0x0003bef4 //!< Send user, login
33#define TS_CMD_RECV_SERVER 0x0004bef4 //!< Recv server Information
34#define TS_CMD_SEND_DEFAULT 0x0005bef0 //!< Send default channel
35#define TS_CMD_RECV_CHANNEL 0x0006bef0 //!< Recv channels
36#define TS_CMD_RECV_USER 0x0007bef0 //!< Recv users
37#define TS_CMD_RECV_ACK 0x0000bef1 //!< Recv acknowledge
38#define TS_CMD_SEND_ACK 0xff00bef1 //!< pseudo command, send recv same id
39#define TS_CMD_RECV_URL 0x0008bef0 //!< Recv ISP Url
40#define TS_CMD_SEND_PING 0x0001bef4 //!< Send ping
41#define TS_CMD_RECV_PING 0x0002bef4 //!< Recv ping
42#define TS_CMD_SEND_LOGOUT 0x012cbef0 //!< Send logout user
43#define TS_CMD_RECV_LOGOUT 0x0065bef0 //!< Recv logout information
44#define TS_CMD_RECV_ADD_PLAYER 0x0064bef0 //!< Recv player login
45#define TS_CMD_RECV_PLAYER_FLAGS 0x0068bef0 //!< Recv player flags
46#define TS_CMD_RECV_ADD_CHANNEL 0x006ebef0 //!< Recv add channel
47#define TS_CMD_RECV_MOVE_PLAYER 0x0067bef0 //!< Recv move player
48#define TS_CMD_RECV_MOVE_PLAYER2 0x006dbef0 //!< Recv move player
49#define TS_CMD_RECV_DEL_CHANNEL 0x0073bef0 //!< Recv delete channel
50#define TS_CMD_RECV_SERVER_UPDATE 0x008cbef0 //!< Recv update server
51#define TS_CMD_SEND_ADD_CHANNEL 0x00c9bef0 //!< Send create channel
52#define TS_CMD_SEND_DEL_CHANNEL 0x00d1bef0 //!< Send delete channel
53#define TS_CMD_SEND_MOVE_PLAYER 0x014abef0 //!< Send move player
54#define TS_CMD_SEND_KICK_PLAYER 0x012dbef0 //!< Send kick player
55
56#define TS_CMD_SEND_SET_CHANNEL_PASSWORD 0x00cbbef0 //!< Send change channel
57#define TS_CMD_SEND_SET_CHANNEL_NAME 0x00cebef0 //!< Send change channel
58#define TS_CMD_SEND_SET_CHANNEL_TOPIC 0x00cfbef0 //!< Send change channel
59#define TS_CMD_SEND_SET_CHANNEL_DESCRIPTION 0x00d0bef0 //!< Send change channel
60#define TS_CMD_SEND_SET_CHANNEL_MAXPLAYERS 0x00d2bef0 //!< Send change channel
61#define TS_CMD_SEND_SET_CHANNEL_FLAGSCODEC 0x00cdbef0 //!< Send change channel
62#define TS_CMD_SEND_SET_CHANNEL_ORDER 0x00d4bef0 //!< Send change channel
63
64#define TS_CMD_RECV_SET_CHANNEL_NAME 0x006fbef0 //!< Recv change channel
65#define TS_CMD_RECV_SET_CHANNEL_TOPIC 0x0070bef0 //!< Recv change channel
66#define TS_CMD_RECV_SET_CHANNEL_DESCRIPTION 0x0072bef0 //!< Recv change channel
67#define TS_CMD_RECV_SET_CHANNEL_MAXPLAYERS 0x0074bef0 //!< Recv change channel
68#define TS_CMD_RECV_SET_CHANNEL_FLAGSCODEC 0x0071bef0 //!< Recv change channel
69#define TS_CMD_RECV_SET_CHANNEL_ORDER 0x0075bef0 //!< Recv change channel
70
71#define TS_CMD_RECV_CHANNEL_PASSWORD_CHANGED 0x00ccbef0 //!< Recv channel password changed
72
73//------------------------------------------------------------------------------
74//! ABC TeamSpeak command.
75/*! Abstract base class for processing commands
76 */
77class TSCommand : public wxObject
78{
79 DECLARE_CLASS(TSCommand)
80 public:
81 /*! CTor
82 */
83 TSCommand(wxUint32 const &id) : m_Id(id)
84 {
85 }
86
87 /*! DTor
88 */
89 virtual ~TSCommand()
90 {
91 }
92
93 /*! Check if this is the right class.
94 * \param id Command id.
95 * \return True if successful.
96 */
97 virtual bool IsCommand(wxUint32 const &id)
98 {
99 if(m_Id == id) return true;
100 else return false;
101 }
102
103 /*! Precess a command.
104 * \param istrm Input stream.
105 * \param ostrm Output stream.
106 * \param cmd TSCmd object.
107 * \return True if successful.
108 */
109 virtual bool ProcessCommand(wxInputStream &istrm,
110 wxOutputStream &ostrm,
111 TSCmd *cmd) = 0;
112
113 /*! Gets the LastError message, call this method
114 * to get more information for an error.
115 * \return LastError message.
116 */
117 wxString const &GetLastError() const
118 {
119 return m_LastError;
120 }
121
122 /*! Get command id.
123 * \return Command id.
124 */
125 wxUint32 GetId() const
126 {
127 return m_Id;
128 }
129
130 protected:
131 //Sets the LastError message.
132 void SetLastError(wxString const &str)
133 {
134 m_LastError = str;
135 }
136
137 const wxUint32 m_Id;
138 wxString m_LastError;
139 //class variable
140 static wxUint32 m_Cnt;
141};
142
143
144//------------------------------------------------------------------------------
145//! TSCmdSendUser
146class TSCmdSendLogin : public TSCommand
147{
148 public:
149 TSCmdSendLogin():TSCommand(TS_CMD_SEND_LOGIN){}
150 //! See baseclass TSCommand for description.
151 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
152};
153
154//------------------------------------------------------------------------------
155//! TSCmdRecvServer
156class TSCmdRecvServer : public TSCommand
157{
158 public:
159 TSCmdRecvServer():TSCommand(TS_CMD_RECV_SERVER){}
160 //! See baseclass TSCommand for description.
161 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
162};
163
164//------------------------------------------------------------------------------
165//! TSCmdSendDefault
166class TSCmdSendDefault : public TSCommand
167{
168 public:
169 TSCmdSendDefault():TSCommand(TS_CMD_SEND_DEFAULT){}
170 //! See baseclass TSCommand for description.
171 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
172};
173
174//------------------------------------------------------------------------------
175//! TSCmdRecvChannel
176class TSCmdRecvChannel : public TSCommand
177{
178 public:
179 TSCmdRecvChannel():TSCommand(TS_CMD_RECV_CHANNEL){}
180 //! See baseclass TSCommand for description.
181 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
182};
183
184//------------------------------------------------------------------------------
185//! TSCmdRecvUser
186class TSCmdRecvUser : public TSCommand
187{
188 public:
189 TSCmdRecvUser():TSCommand(TS_CMD_RECV_USER){}
190 //! See baseclass TSCommand for description.
191 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
192};
193
194//------------------------------------------------------------------------------
195//! TSCmdSendAck
196class TSCmdSendAck : public TSCommand
197{
198 public:
199 TSCmdSendAck():TSCommand(TS_CMD_SEND_ACK){}
200 //! See baseclass TSCommand for description.
201 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
202};
203
204//------------------------------------------------------------------------------
205//! TSCmdRecvAck
206class TSCmdRecvAck : public TSCommand
207{
208 public:
209 TSCmdRecvAck():TSCommand(TS_CMD_RECV_ACK){}
210 //! See baseclass TSCommand for description.
211 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
212};
213
214//------------------------------------------------------------------------------
215//! TSCmdRecvUrl
216class TSCmdRecvUrl : public TSCommand
217{
218 public:
219 TSCmdRecvUrl():TSCommand(TS_CMD_RECV_URL){}
220 //! See baseclass TSCommand for description.
221 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
222};
223
224//------------------------------------------------------------------------------
225//! TSCmdSendPing
226class TSCmdSendPing : public TSCommand
227{
228 public:
229 TSCmdSendPing():TSCommand(TS_CMD_SEND_PING){}
230 //! See baseclass TSCommand for description.
231 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
232};
233
234//------------------------------------------------------------------------------
235//! TSCmdRecvPing
236class TSCmdRecvPing : public TSCommand
237{
238 public:
239 TSCmdRecvPing():TSCommand(TS_CMD_RECV_PING){}
240 //! See baseclass TSCommand for description.
241 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
242};
243
244//------------------------------------------------------------------------------
245//! TSCmdSendLogout
246class TSCmdSendLogout : public TSCommand
247{
248 public:
249 TSCmdSendLogout():TSCommand(TS_CMD_SEND_LOGOUT){}
250 //! See baseclass TSCommand for description.
251 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
252};
253
254//------------------------------------------------------------------------------
255//! TSCmdRecvLogoutInfo
256class TSCmdRecvLogout : public TSCommand
257{
258 public:
259 TSCmdRecvLogout():TSCommand(TS_CMD_RECV_LOGOUT){}
260 //! See baseclass TSCommand for description.
261 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
262};
263
264//------------------------------------------------------------------------------
265//! TSCmdRecvAddPlayer
266class TSCmdRecvAddPlayer : public TSCommand
267{
268 public:
269 TSCmdRecvAddPlayer():TSCommand(TS_CMD_RECV_ADD_PLAYER){}
270 //! See baseclass TSCommand for description.
271 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
272};
273
274//------------------------------------------------------------------------------
275//! TSCmdRecvPlayerFlags
276class TSCmdRecvPlayerFlags : public TSCommand
277{
278 public:
279 TSCmdRecvPlayerFlags():TSCommand(TS_CMD_RECV_PLAYER_FLAGS){}
280 //! See baseclass TSCommand for description.
281 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
282};
283
284//------------------------------------------------------------------------------
285//! TSCmdRecvAddChannel
286class TSCmdRecvAddChannel : public TSCommand
287{
288 public:
289 TSCmdRecvAddChannel():TSCommand(TS_CMD_RECV_ADD_CHANNEL){}
290 //! See baseclass TSCommand for description.
291 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
292};
293
294//------------------------------------------------------------------------------
295//! TSCmdRecvMovePlayer
296class TSCmdRecvMovePlayer : public TSCommand
297{
298 public:
299 TSCmdRecvMovePlayer():TSCommand(TS_CMD_RECV_MOVE_PLAYER){}
300 //! See baseclass TSCommand for description.
301 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
302};
303
304//------------------------------------------------------------------------------
305//! TSCmdRecvMovePlayer
306class TSCmdRecvMovePlayer2 : public TSCommand
307{
308 public:
309 TSCmdRecvMovePlayer2():TSCommand(TS_CMD_RECV_MOVE_PLAYER2){}
310 //! See baseclass TSCommand for description.
311 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
312};
313
314//------------------------------------------------------------------------------
315//! TSCmdRecvDelChannel
316class TSCmdRecvDelChannel : public TSCommand
317{
318 public:
319 TSCmdRecvDelChannel():TSCommand(TS_CMD_RECV_DEL_CHANNEL){}
320 //! See baseclass TSCommand for description.
321 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
322};
323
324//------------------------------------------------------------------------------
325//! TSCmdRecvServerUpdate
326class TSCmdRecvServerUpdate : public TSCommand
327{
328 public:
329 TSCmdRecvServerUpdate():TSCommand(TS_CMD_RECV_SERVER_UPDATE){}
330 //! See baseclass TSCommand for description.
331 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
332};
333
334//------------------------------------------------------------------------------
335//! TSCmdSendAddChannel
336class TSCmdSendAddChannel : public TSCommand
337{
338 public:
339 TSCmdSendAddChannel():TSCommand(TS_CMD_SEND_ADD_CHANNEL){}
340 //! See baseclass TSCommand for description.
341 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
342};
343
344//------------------------------------------------------------------------------
345//! TSCmdSendDelChannel
346class TSCmdSendDelChannel : public TSCommand
347{
348 public:
349 TSCmdSendDelChannel():TSCommand(TS_CMD_SEND_DEL_CHANNEL){}
350 //! See baseclass TSCommand for description.
351 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
352};
353
354//------------------------------------------------------------------------------
355//! TSCmdSendMovePlayer
356class TSCmdSendMovePlayer : public TSCommand
357{
358 public:
359 TSCmdSendMovePlayer():TSCommand(TS_CMD_SEND_MOVE_PLAYER){}
360 //! See baseclass TSCommand for description.
361 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
362};
363
364//------------------------------------------------------------------------------
365//! TSCmdSendSetChannelPassword
366class TSCmdSendSetChannelPassword : public TSCommand
367{
368 public:
369 TSCmdSendSetChannelPassword():TSCommand(TS_CMD_SEND_SET_CHANNEL_PASSWORD){}
370 //! See baseclass TSCommand for description.
371 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
372};
373
374//------------------------------------------------------------------------------
375//! TSCmdSendSetChannelName
376class TSCmdSendSetChannelName : public TSCommand
377{
378 public:
379 TSCmdSendSetChannelName():TSCommand(TS_CMD_SEND_SET_CHANNEL_NAME){}
380 //! See baseclass TSCommand for description.
381 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
382};
383
384//------------------------------------------------------------------------------
385//! TSCmdSendSetChannelTopic
386class TSCmdSendSetChannelTopic : public TSCommand
387{
388 public:
389 TSCmdSendSetChannelTopic():TSCommand(TS_CMD_SEND_SET_CHANNEL_TOPIC){}
390 //! See baseclass TSCommand for description.
391 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
392};
393
394//------------------------------------------------------------------------------
395//! TSCmdSendSetChannelDescription
396class TSCmdSendSetChannelDescription : public TSCommand
397{
398 public:
399 TSCmdSendSetChannelDescription():TSCommand(TS_CMD_SEND_SET_CHANNEL_DESCRIPTION){}
400 //! See baseclass TSCommand for description.
401 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
402};
403
404//------------------------------------------------------------------------------
405//! TSCmdSendSetChannelMaxPlayers
406class TSCmdSendSetChannelMaxPlayers : public TSCommand
407{
408 public:
409 TSCmdSendSetChannelMaxPlayers():TSCommand(TS_CMD_SEND_SET_CHANNEL_MAXPLAYERS){}
410 //! See baseclass TSCommand for description.
411 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
412};
413
414//------------------------------------------------------------------------------
415//! TSCmdSendSetChannelFlagsCodec
416class TSCmdSendSetChannelFlagsCodec : public TSCommand
417{
418 public:
419 TSCmdSendSetChannelFlagsCodec():TSCommand(TS_CMD_SEND_SET_CHANNEL_FLAGSCODEC){}
420 //! See baseclass TSCommand for description.
421 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
422};
423
424//------------------------------------------------------------------------------
425//! TSCmdSendSetChannelOrder
426class TSCmdSendSetChannelOrder : public TSCommand
427{
428 public:
429 TSCmdSendSetChannelOrder():TSCommand(TS_CMD_SEND_SET_CHANNEL_ORDER){}
430 //! See baseclass TSCommand for description.
431 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
432};
433
434//------------------------------------------------------------------------------
435//! TSCmdRecvSetChannelName
436class TSCmdRecvSetChannelName : public TSCommand
437{
438 public:
439 TSCmdRecvSetChannelName():TSCommand(TS_CMD_RECV_SET_CHANNEL_NAME){}
440 //! See baseclass TSCommand for description.
441 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
442};
443
444//------------------------------------------------------------------------------
445//! TSCmdRecvSetChannelTopic
446class TSCmdRecvSetChannelTopic : public TSCommand
447{
448 public:
449 TSCmdRecvSetChannelTopic():TSCommand(TS_CMD_RECV_SET_CHANNEL_TOPIC){}
450 //! See baseclass TSCommand for description.
451 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
452};
453
454//------------------------------------------------------------------------------
455//! TSCmdRecvSetChannelDescription
456class TSCmdRecvSetChannelDescription : public TSCommand
457{
458 public:
459 TSCmdRecvSetChannelDescription():TSCommand(TS_CMD_RECV_SET_CHANNEL_DESCRIPTION){}
460 //! See baseclass TSCommand for description.
461 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
462};
463
464//------------------------------------------------------------------------------
465//! TSCmdRecvSetChannelMaxPlayers
466class TSCmdRecvSetChannelMaxPlayers : public TSCommand
467{
468 public:
469 TSCmdRecvSetChannelMaxPlayers():TSCommand(TS_CMD_RECV_SET_CHANNEL_MAXPLAYERS){}
470 //! See baseclass TSCommand for description.
471 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
472};
473
474//------------------------------------------------------------------------------
475//! TSCmdRecvSetChannelFlagsCodec
476class TSCmdRecvSetChannelFlagsCodec : public TSCommand
477{
478 public:
479 TSCmdRecvSetChannelFlagsCodec():TSCommand(TS_CMD_RECV_SET_CHANNEL_FLAGSCODEC){}
480 //! See baseclass TSCommand for description.
481 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
482};
483
484//------------------------------------------------------------------------------
485//! TSCmdRecvSetChannelOrder
486class TSCmdRecvSetChannelOrder : public TSCommand
487{
488 public:
489 TSCmdRecvSetChannelOrder():TSCommand(TS_CMD_RECV_SET_CHANNEL_ORDER){}
490 //! See baseclass TSCommand for description.
491 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
492};
493
494//------------------------------------------------------------------------------
495//! TSCmdSendKickPlayer
496class TSCmdSendKickPlayer : public TSCommand
497{
498 public:
499 TSCmdSendKickPlayer():TSCommand(TS_CMD_SEND_KICK_PLAYER){}
500 //! See baseclass TSCommand for description.
501 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
502};
503
504//------------------------------------------------------------------------------
505//! TSCmdRecvChannelPasswordChanged
506class TSCmdRecvChannelPasswordChanged : public TSCommand
507{
508 public:
509 TSCmdRecvChannelPasswordChanged():TSCommand(TS_CMD_RECV_CHANNEL_PASSWORD_CHANGED){}
510 //! See baseclass TSCommand for description.
511 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
512};
513
514//------------------------------------------------------------------------------
515//! TSCmdRecvUnknown
516class TSCmdRecvUnknown : public TSCommand
517{
518 public:
519 TSCmdRecvUnknown():TSCommand(TS_CMD_RECV_UNKNOWN){}
520 //! See baseclass TSCommand for description.
521 virtual bool ProcessCommand(wxInputStream &istrm, wxOutputStream &ostrm, TSCmd *cmd);
522};
523
524#endif
diff --git a/tsconnectionthread.cpp b/tsconnectionthread.cpp
new file mode 100644
index 0000000..018afdf
--- /dev/null
+++ b/tsconnectionthread.cpp
@@ -0,0 +1,728 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tsconnectionthread.h"
21#include "wxbufferex.h"
22
23//Libraries
24#include <wx/txtstrm.h>
25#include <wx/mstream.h>
26#include <wx/buffer.h>
27#include <wx/sckstrm.h>
28#include <wx/sstream.h>
29#include <wx/listimpl.cpp>
30
31WX_DEFINE_LIST(TSQueue);
32
33IMPLEMENT_CLASS(TSConnectionThread, wxObject)
34
35//------------------------------------------------------------------------------
36// Default CTor, Initializes the object
37TSConnectionThread::TSConnectionThread(TSClient *client, wxMutex *mutex)
38 : wxThread(wxTHREAD_JOINABLE)
39{
40 m_pMutex = mutex;
41
42 Create();
43 m_pClient = client;
44 m_ppCommands = new TSpCommandArray;
45 m_pMySock = new wxDatagramSocket(m_ClientAddr);
46 m_InQueue = new TSQueue;
47 m_OutQueue = new TSQueue;
48
49 m_Exit = false;
50 m_Error = false;
51 m_Timer = false;
52 m_pCurCmd = NULL;
53 m_LocalCmd = true;
54 m_Connected = false;
55 m_pMySock = NULL;
56
57 //register known commands
58 RegisterCommand(new TSCmdSendLogin);
59 RegisterCommand(new TSCmdRecvServer);
60 RegisterCommand(new TSCmdSendDefault);
61 RegisterCommand(new TSCmdRecvChannel);
62 RegisterCommand(new TSCmdRecvUser);
63 RegisterCommand(new TSCmdRecvAck);
64 RegisterCommand(new TSCmdSendAck);
65 RegisterCommand(new TSCmdRecvUrl);
66 RegisterCommand(new TSCmdSendPing);
67 RegisterCommand(new TSCmdRecvPing);
68 RegisterCommand(new TSCmdSendLogout);
69 RegisterCommand(new TSCmdRecvLogout);
70 RegisterCommand(new TSCmdRecvAddPlayer);
71 RegisterCommand(new TSCmdRecvPlayerFlags);
72 RegisterCommand(new TSCmdRecvAddChannel);
73 RegisterCommand(new TSCmdRecvMovePlayer);
74 RegisterCommand(new TSCmdRecvMovePlayer2);
75 RegisterCommand(new TSCmdRecvDelChannel);
76 RegisterCommand(new TSCmdRecvServerUpdate);
77 RegisterCommand(new TSCmdSendAddChannel);
78 RegisterCommand(new TSCmdSendDelChannel);
79 RegisterCommand(new TSCmdSendMovePlayer);
80 RegisterCommand(new TSCmdSendSetChannelPassword);
81 RegisterCommand(new TSCmdSendSetChannelName);
82 RegisterCommand(new TSCmdSendSetChannelTopic);
83 RegisterCommand(new TSCmdSendSetChannelDescription);
84 RegisterCommand(new TSCmdSendSetChannelMaxPlayers);
85 RegisterCommand(new TSCmdSendSetChannelFlagsCodec);
86 RegisterCommand(new TSCmdSendSetChannelOrder);
87 RegisterCommand(new TSCmdRecvSetChannelName);
88 RegisterCommand(new TSCmdRecvSetChannelTopic);
89 RegisterCommand(new TSCmdRecvSetChannelDescription);
90 RegisterCommand(new TSCmdRecvSetChannelMaxPlayers);
91 RegisterCommand(new TSCmdRecvSetChannelFlagsCodec);
92 RegisterCommand(new TSCmdRecvSetChannelOrder);
93 RegisterCommand(new TSCmdSendKickPlayer);
94 RegisterCommand(new TSCmdRecvChannelPasswordChanged);
95
96 //for all unknown commands
97 RegisterCommand(new TSCmdRecvUnknown);
98}
99
100//------------------------------------------------------------------------------
101//Default DTor
102TSConnectionThread::~TSConnectionThread()
103{
104 /* DON'T USE THIS */
105}
106
107//------------------------------------------------------------------------------
108// thread execution starts here
109wxThread::ExitCode TSConnectionThread::Entry()
110{
111 wxLogMessage(_T("TSConnection: thread started."));
112
113 m_ClientAddr.AnyAddress();
114 m_ClientAddr.Service(0);
115
116 m_ServerAddr.Hostname(m_pClient->GetServer()->GetServerAddress());
117 m_ServerAddr.Service(m_pClient->GetServer()->GetPort());
118
119 //no methode to reset socket
120 if (m_pMySock)
121 {
122 wxASSERT(m_pMySock != NULL);
123 m_pMySock->Destroy();
124 m_pMySock = NULL;
125 }
126
127 m_pMySock = new wxDatagramSocket(m_ClientAddr);
128 if(m_pMySock->Error())
129 {
130 wxLogError(_T("creating socket, terminating thread."));
131 return wxThread::ExitCode(EXIT_FAILURE);
132 }
133
134 m_pMySock->SetTimeout(SOCKET_TIMEOUT);
135
136 //empty dgram to initialize and remember peer
137 //allows us to use wxSocketOutputStream afterwards
138 m_pMySock->SendTo(m_ServerAddr, NULL, 0);
139
140 if(!MainLoop())
141 {
142 wxLogDebug(_T("Error: %s"), GetLastError().c_str());
143 return wxThread::ExitCode(EXIT_FAILURE);
144 }
145
146 return wxThread::ExitCode(EXIT_SUCCESS);
147}
148
149//------------------------------------------------------------------------------
150// and stops here
151void TSConnectionThread::OnExit()
152{
153 wxLogDebug(_T("TSConnection: thread terminated."));
154
155 //do the necessary cleanup
156 for(size_t i = 0; i < m_ppCommands->GetCount(); i++)
157 delete m_ppCommands->Item(i);
158
159 m_InQueue->DeleteContents(true);
160 m_OutQueue->DeleteContents(true);
161
162 wxASSERT(m_InQueue != NULL);
163 delete m_InQueue;
164 m_InQueue = NULL;
165
166 wxASSERT(m_OutQueue != NULL);
167 delete m_OutQueue;
168 m_OutQueue = NULL;
169
170 wxASSERT(m_ppCommands != NULL);
171 delete m_ppCommands;
172 m_ppCommands = NULL;
173
174 wxASSERT(m_pMySock != NULL);
175 m_pMySock->Destroy();
176 m_pMySock = NULL;
177
178 if(m_pCurCmd != NULL)
179 {
180 delete m_pCurCmd;
181 m_pCurCmd = NULL;
182 }
183}
184
185//------------------------------------------------------------------------------
186// SyncSendCmdError
187bool TSConnectionThread::SyncSendCmdLastError()
188{
189 //wxLogDebug(_T("SyncSendCmdLastError"));
190 m_LocalCmd = true;
191
192 m_SWTimeout.Start();
193 m_SWTimeout.Pause();
194
195 TSCmd *cmd = m_pClient->GetSync();
196 cmd->error = true;
197 cmd->lasterror = m_LastError;
198 cmd->executed = true;
199 m_pClient->m_Lock = false;
200 return true;
201}
202
203//------------------------------------------------------------------------------
204// Sync with TSClient and send command
205bool TSConnectionThread::SyncSendCmd()
206{
207 //wxLogDebug(_T("SyncSendCmd"));
208 TSCmd *cmd = m_pClient->GetSync();
209 m_pCurCmd = cmd;
210
211 if(cmd->id == 0)
212 {
213 SetLastError(_T("no command id"));
214 SyncSendCmdLastError();
215 return true;
216 }
217
218 if(cmd->id != TS_CMD_SEND_LOGIN &&
219 cmd->id != TS_CMD_SEND_DEFAULT &&
220 !m_Connected)
221 {
222 SetLastError(_T("no connection to server"));
223 SyncSendCmdLastError();
224 return true;
225 }
226
227 m_LocalCmd = false;
228 SendCommand(cmd);
229
230 return true;
231}
232
233//------------------------------------------------------------------------------
234// Register a Command, the class takes care of this pointer.
235void TSConnectionThread::RegisterCommand(TSCommand *cmd)
236{
237 wxASSERT(cmd != NULL);
238 m_ppCommands->Add(cmd);
239}
240
241//------------------------------------------------------------------------------
242// Executes a command.
243bool TSConnectionThread::ExecuteCommand(wxInputStream &istrm,
244 wxOutputStream &ostrm,
245 TSCmd *cmd)
246{
247 wxLogDebug(_T("ExecuteCommand: 0x%X"), cmd->id);
248 for(size_t i = 0; i < m_ppCommands->GetCount(); i++)
249 {
250 if(m_ppCommands->Item(i)->IsCommand(cmd->id))
251 {
252 if(m_ppCommands->Item(i)->ProcessCommand(istrm, ostrm, cmd))
253 return true;
254 else
255 {
256 SetLastError(m_ppCommands->Item(i)->GetLastError());
257 return false;
258 }
259 }
260 }
261
262 #ifdef IGNORE_UNKNOWN_COMMANDS
263 //used for unknown commands
264 cmd->id = TS_CMD_RECV_UNKNOWN;
265 return ExecuteCommand(istrm, ostrm, cmd);
266 #else
267 SetLastError(_T("invalid command"));
268 return false;
269 #endif
270}
271
272//------------------------------------------------------------------------------
273// Dumps object.
274void TSConnectionThread::Dump(wxOutputStream &ostrm) const
275{
276 wxTextOutputStream out(ostrm);
277 out << _T("Object: TSConnection (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl;
278 out << _T("-wxString m_LastError: ") << m_LastError << endl;
279}
280
281//------------------------------------------------------------------------------
282// send command.
283bool TSConnectionThread::SendOutputCommand(TSCmd *cmd)
284{
285 //wxLogDebug(_T("SendOutputCommand: 0x%X"), cmd->id);
286 if(!SendCommandToSocket(cmd))
287 return false;
288
289 /* this m_pCurCmd code possibly contains a memleak
290 * the lines below solves ~95% of them
291 */
292 /*if(m_pCurCmd != NULL)
293 {
294 delete m_pCurCmd;
295 m_pCurCmd = NULL;
296 }*/
297
298 switch(cmd->id)
299 {
300 case TS_CMD_SEND_LOGIN:
301 AddInputCommand(new TSCmd(TS_CMD_RECV_SERVER, cmd));
302 m_pCurCmd = new TSCmd(TS_CMD_RECV_SERVER, cmd);
303 break;
304 case TS_CMD_SEND_DEFAULT:
305 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
306 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
307 break;
308 case TS_CMD_SEND_PING:
309 AddInputCommand(new TSCmd(TS_CMD_RECV_PING, cmd));
310 m_pCurCmd = new TSCmd(TS_CMD_RECV_PING, cmd);
311 break;
312 case TS_CMD_SEND_LOGOUT:
313 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
314 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
315 break;
316 case TS_CMD_SEND_ADD_CHANNEL:
317 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
318 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
319 break;
320 case TS_CMD_SEND_DEL_CHANNEL:
321 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
322 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
323 break;
324 case TS_CMD_SEND_MOVE_PLAYER:
325 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
326 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
327 break;
328 case TS_CMD_SEND_SET_CHANNEL_PASSWORD:
329 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
330 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
331 break;
332 case TS_CMD_SEND_SET_CHANNEL_NAME:
333 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
334 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
335 break;
336 case TS_CMD_SEND_SET_CHANNEL_TOPIC:
337 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
338 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
339 break;
340 case TS_CMD_SEND_SET_CHANNEL_DESCRIPTION:
341 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
342 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
343 break;
344 case TS_CMD_SEND_SET_CHANNEL_MAXPLAYERS:
345 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
346 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
347 break;
348 case TS_CMD_SEND_SET_CHANNEL_FLAGSCODEC:
349 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
350 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
351 break;
352 case TS_CMD_SEND_SET_CHANNEL_ORDER:
353 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
354 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
355 break;
356 case TS_CMD_SEND_KICK_PLAYER:
357 AddInputCommand(new TSCmd(TS_CMD_RECV_ACK, cmd));
358 m_pCurCmd = new TSCmd(TS_CMD_RECV_ACK, cmd);
359 break;
360 case TS_CMD_SEND_ACK:
361 break;
362 }
363
364 return true;
365}
366
367//------------------------------------------------------------------------------
368// SendQueuedCommand.
369bool TSConnectionThread::SendQueuedCommand()
370{
371 //wxLogDebug(_T("SendQueuedCommand"));
372 wxTSQueueNode *node = m_OutQueue->GetFirst();
373 TSCmd *t = node->GetData();
374 if(!SendOutputCommand(t))
375 return false;
376
377 delete t;
378 if(!m_OutQueue->DeleteNode(node))
379 {
380 SetLastError(_T("deleting node"));
381 return false;
382 }
383
384 return true;
385}
386
387//------------------------------------------------------------------------------
388// Send command.
389bool TSConnectionThread::SendCommand(TSCmd *cmd)
390{
391 //wxLogDebug(_T("SendCommand: 0x%X"), cmd->id);
392 if(m_pCurCmd == NULL)
393 m_pCurCmd = cmd;
394
395 m_SWTimeout.Start();
396
397 if(!SendOutputCommand(cmd))
398 return false;
399 m_Retries = 0;
400 return true;
401}
402
403//------------------------------------------------------------------------------
404// Send command to socket.
405bool TSConnectionThread::SendCommandToSocket(TSCmd *cmd)
406{
407 //wxLogDebug(_T("SendCommandToSocket: 0x%X"), cmd->id);
408 wxLogVerbose(_T("TSClient: command %#x sent"),cmd->id);
409
410 wxSocketOutputStream so(*m_pMySock);
411 wxBufferedOutputStream out(so);
412 wxSocketInputStream si(*m_pMySock);
413 wxBufferedInputStream in(si);
414
415 if(!ExecuteCommand(in, out, cmd))
416 {
417 SetLastError(_T("execute command"));
418 return false;
419 }
420
421 out.Sync();
422 return true;
423}
424
425//------------------------------------------------------------------------------
426// Add command.
427void TSConnectionThread::AddOutputCommand(TSCmd *cmd)
428{
429 //wxLogDebug(_T("AddOutputCommand: 0x%X"), cmd->id);
430 m_OutQueue->Append(cmd);
431}
432
433//------------------------------------------------------------------------------
434// CheckInputQueue
435bool TSConnectionThread::CheckInputQueue(TSCmd *cmd)
436{
437 wxLogDebug(_T("CheckInputQueue: 0x%X, 0x%X"), cmd->id, cmd->pktid);
438
439 switch(cmd->id)
440 {
441 case TS_CMD_RECV_CHANNEL:
442 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
443 break;
444 case TS_CMD_RECV_USER:
445 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
446 break;
447 case TS_CMD_RECV_URL:
448 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
449 wxLogVerbose(_T("TSClient: connected"));
450 m_Connected = true;
451 m_Timer = true;
452 break;
453 case TS_CMD_RECV_LOGOUT:
454 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
455 break;
456 case TS_CMD_RECV_UNKNOWN:
457 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
458 break;
459 case TS_CMD_RECV_ACK:
460 break;
461 case TS_CMD_RECV_SERVER:
462 //AddOutputCommand(new TSCmd(TS_CMD_SEND_DEFAULT, cmd));
463 break;
464 case TS_CMD_RECV_ADD_PLAYER:
465 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
466 break;
467 case TS_CMD_RECV_PLAYER_FLAGS:
468 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
469 break;
470 case TS_CMD_RECV_ADD_CHANNEL:
471 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
472 break;
473 case TS_CMD_RECV_MOVE_PLAYER:
474 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
475 break;
476 case TS_CMD_RECV_MOVE_PLAYER2:
477 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
478 break;
479 case TS_CMD_RECV_DEL_CHANNEL:
480 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
481 break;
482 case TS_CMD_RECV_SERVER_UPDATE:
483 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
484 // force reconnect for the sake of consistency
485 AddOutputCommand(new TSCmd(TS_CMD_SEND_LOGOUT, cmd));
486 break;
487 case TS_CMD_RECV_SET_CHANNEL_NAME:
488 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
489 break;
490 case TS_CMD_RECV_SET_CHANNEL_TOPIC:
491 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
492 break;
493 case TS_CMD_RECV_SET_CHANNEL_DESCRIPTION:
494 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
495 break;
496 case TS_CMD_RECV_SET_CHANNEL_MAXPLAYERS:
497 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
498 break;
499 case TS_CMD_RECV_SET_CHANNEL_FLAGSCODEC:
500 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
501 break;
502 case TS_CMD_RECV_SET_CHANNEL_ORDER:
503 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
504 break;
505 case TS_CMD_RECV_CHANNEL_PASSWORD_CHANGED:
506 AddOutputCommand(new TSCmd(TS_CMD_SEND_ACK, cmd));
507 break;
508 case TS_CMD_RECV_PING:
509 break;
510 default:
511 wxLogWarning(_T("input queue: invalid command %#x, ignoring"), cmd->id);
512 break;
513 }
514
515 for(wxTSQueueNode *node = m_InQueue->GetFirst(); node != NULL; node = node->GetNext())
516 {
517 TSCmd *cur = node->GetData();
518 //cmd found
519 if(cur->id == cmd->id)
520 {
521 delete cur;
522 if(!m_InQueue->DeleteNode(node))
523 {
524 SetLastError(_T("deleting node"));
525 return false;
526 }
527 //return true;
528 }
529
530 if(m_pCurCmd->id == cmd->id)
531 {
532 m_pMutex->Lock();
533
534 wxLogDebug(_T("found in queue: 0x%X"), cmd->id);
535 delete m_pCurCmd;
536 m_pCurCmd = NULL;
537 if (!m_LocalCmd)
538 {
539 m_pClient->m_Lock = false;
540 m_pClient->GetSync()->executed = true;
541 }
542 m_LocalCmd = true;
543
544 m_SWTimeout.Pause();
545
546 m_pMutex->Unlock();
547
548 return true;
549 }
550 }
551
552 return true;
553}
554
555//------------------------------------------------------------------------------
556// ReadQueuedCommand.
557bool TSConnectionThread::RecvCommand()
558{
559 wxSocketOutputStream so(*m_pMySock);
560 wxMemoryBufferEx buf(1024);
561 m_pMySock->RecvFrom(m_ServerAddr, buf.GetData(), 1024);
562 buf.SetDataLen(m_pMySock->LastCount());
563 wxMemoryInputStream in(buf.GetData(), buf.GetDataLen());
564 wxDataInputStream data(in);
565
566 TSCmd cmd;
567 cmd.id = data.Read32(); //read id
568 data.Read32(); //Session id
569 data.Read32(); //Player id
570 cmd.pktid = data.Read32(); //Packet count
571 cmd.client = m_pClient;
572 in.SeekI(0);
573
574 wxLogVerbose(_T("TSClient: command %#x received"), cmd.id);
575
576 // dirty workaround for crappy teamspeak protocol, which splits off pakets
577 if(cmd.id == TS_CMD_RECV_CHANNEL)
578 {
579 in.SeekI(-1, wxFromEnd);
580 if(data.Read8() != 0)
581 {
582 wxMemoryBuffer buf_b2(1024);
583 m_pMySock->RecvFrom(m_ServerAddr, buf_b2.GetData(), 1024);
584 buf_b2.SetDataLen(m_pMySock->LastCount());
585 wxMemoryInputStream in_b2(buf_b2.GetData(), buf_b2.GetDataLen());
586 wxDataInputStream data_b2(in_b2);
587
588 if(data_b2.Read32() != cmd.id)
589 {
590 SetLastError(_T("invalid command, perhaps wrong paket order (udp?)"));
591 return false;
592 }
593
594 data_b2.Read32(); //Session id
595 data_b2.Read32(); //Player id
596 cmd.pktid = data_b2.Read32(); //Packet count
597 data_b2.Read32(); //read unknown
598 data_b2.Read32(); //CRC
599
600 // send acknowledge for 2nd packet
601 if(!CheckInputQueue(&cmd))
602 return false;
603
604 // append bytes
605 while(!in_b2.Eof())
606 buf.AppendByte(in_b2.GetC());
607 }
608 in.SeekI(0);
609 }
610
611 // update streams (dirty, but copy-operator is private)
612 wxMemoryInputStream in2(buf.GetData(), buf.GetDataLen());
613 wxDataInputStream data2(in2);
614 if(!ExecuteCommand(in2, so, &cmd))
615 {
616 switch(cmd.id)
617 {
618 case TS_CMD_RECV_SERVER:
619 SyncSendCmdLastError();
620 break;
621 }
622
623 return false;
624 }
625 if(!CheckInputQueue(&cmd))
626 return false;
627
628 return true;
629}
630
631//------------------------------------------------------------------------------
632// Add command.
633void TSConnectionThread::AddInputCommand(TSCmd *cmd)
634{
635 //wxLogDebug(_T("AddInputCommand: 0x%X"), cmd->id);
636 m_InQueue->Append(cmd);
637}
638
639//------------------------------------------------------------------------------
640// StartMainLoop
641bool TSConnectionThread::MainLoop()
642{
643 wxStopWatch sw;
644 sw.Start();
645 m_Retries = 0;
646
647 while(1)
648 {
649 //Is new command available
650 m_pMutex->Lock();
651 if((m_pClient->GetSync() != NULL) &&
652 (m_pCurCmd == NULL) &&
653 (m_pClient->m_Lock) &&
654 (m_OutQueue->GetCount() == 0))
655 {
656 m_SWTimeout.Start();
657 SyncSendCmd();
658 }
659 m_pMutex->Unlock();
660
661 //Is some data in queue
662 if(m_OutQueue->GetCount() != 0)
663 {
664 if(!SendQueuedCommand())
665 return false;
666 }
667
668 //Is new data available
669 if(m_pMySock->IsData())
670 {
671 if(!RecvCommand())
672 return false;
673 }
674
675 //Send ping
676 if((sw.Time() >= PING_INTERMITTENT) && m_Timer)
677 {
678 sw.Start();
679 TSCmd tmp;
680 tmp.client = m_pClient;
681 if(m_pCurCmd == NULL)
682 SendCommand(new TSCmd(TS_CMD_SEND_PING, &tmp));
683 }
684
685 //Check for timeout
686 if(m_SWTimeout.Time() > CMD_TIMEOUT)
687 {
688 SetLastError(_T("command timeout"));
689
690 m_pCurCmd = NULL;
691
692 if(!m_LocalCmd)
693 {
694 SyncSendCmdLastError();
695 }
696
697 m_LocalCmd = true;
698 //reset timer
699 m_SWTimeout.Start();
700 m_SWTimeout.Pause();
701
702 wxLogVerbose(_T("TSClient: disconnected"));
703 m_Connected = false;
704 /*
705 if(++m_Retries <= MAX_RETRIES)
706 {
707 m_Connected = false;
708 }
709 */
710 return false;
711 }
712
713 //Check if we should delete our self
714 if(TestDestroy())
715 return true;
716
717 //If an error occurred, end thread
718 if(m_Error)
719 return false;
720
721 //If m_Exit is set, end thread
722 if(m_Exit)
723 return true;
724
725 Sleep(10);
726 }
727}
728
diff --git a/tsconnectionthread.h b/tsconnectionthread.h
new file mode 100644
index 0000000..2d67be6
--- /dev/null
+++ b/tsconnectionthread.h
@@ -0,0 +1,176 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef TSCONNECTION_H
20#define TSCONNECTION_H
21
22// Libraries
23#include <wx/wx.h>
24#include <wx/socket.h>
25#include <wx/stream.h>
26#include <wx/thread.h>
27#include <wx/list.h>
28#include <wx/stopwatch.h>
29
30#include "tsheaders.h"
31
32//WX_DECLARE_LIST
33WX_DECLARE_LIST_PTR(TSCmd, TSQueue);
34
35//! Repeat ping command after ...milliseconds
36#define PING_INTERMITTENT 1000
37//! Socket timeout ...seconds
38#define SOCKET_TIMEOUT 5
39//! Number of packets t loos for disconnect
40#define MAX_RETRIES 3
41//! Command timeout in milliseconds
42#define CMD_TIMEOUT 5000
43
44
45//! Ignore unknown commands
46#define IGNORE_UNKNOWN_COMMANDS
47
48//! TeamSpeak connection thread.
49/*! TSConnectionThread is used to communicate with the server.
50 * without bocking the main thread.
51 */
52class TSConnectionThread : public wxThread
53{
54 friend class TSClient;
55
56 DECLARE_CLASS(TSConnectionThread)
57
58 public:
59 /*! thread execution starts here
60 * \return Returns ExitCode.
61 */
62 virtual ExitCode Entry();
63
64 /*! and stops here
65 */
66 virtual void OnExit();
67
68 /*! Default CTor, Initializes the object.
69 */
70 TSConnectionThread(TSClient *client, wxMutex *mutex);
71
72 /*! Default DTor.
73 */
74 ~TSConnectionThread();
75
76 /*! Register a command, the class takes care of this pointer.
77 * \param cmd Command.
78 */
79 void RegisterCommand(TSCommand *cmd);
80
81 /*! Start main loop.
82 * \return Returns false if fails, check GetLastError for details.
83 * \sa GetLastError()
84 */
85 bool MainLoop();
86
87 /*! Executes a command.
88 * \param cmd Command.
89 * \return Returns false if fails, check GetLastError for details.
90 * \sa GetLastError()
91 */
92 bool ExecuteCommand(wxInputStream &istrm, wxOutputStream &ostrm,
93 TSCmd *cmd);
94
95 /*! Sync with TSClient and send command.
96 * \return Returns false if fails, check GetLastError for details.
97 * \sa GetLastError()
98 */
99 bool SyncSendCmd();
100
101 /*! Add command.
102 * \param cmd Command.
103 * \return Returns false if fails, check GetLastError for details.
104 * \sa GetLastError()
105 */
106 bool SendOutputCommand(TSCmd *cmd);
107
108 /*! Add command.
109 * \return Returns false if fails, check GetLastError for details.
110 * \sa GetLastError()
111 */
112 bool SendQueuedCommand();
113
114 /*! Add command.
115 * \param cmd Command.
116 * \return Returns false if fails, check GetLastError for details.
117 * \sa GetLastError()
118 */
119 void AddInputCommand(TSCmd *cmd);
120
121 void AddOutputCommand(TSCmd *cmd);
122
123 bool RecvCommand();
124
125 bool CheckInputQueue(TSCmd *cmd);
126
127 /*! Gets the LastError message, call this method
128 * to get more information for an error.
129 * \return LastError message.
130 */
131 wxString const &GetLastError() const
132 {
133 return m_LastError;
134 }
135
136 /*! Dumps object.
137 * \param ostrm Stream to write.
138 */
139 void Dump(wxOutputStream &ostrm) const;
140
141 private:
142 //Sets the LastError message.
143 void SetLastError(wxString const &str)
144 {
145 m_LastError = str;
146 }
147
148 // Send command
149 bool SendCommand(TSCmd *cmd);
150
151 // Send command to socket
152 bool SendCommandToSocket(TSCmd *cmd);
153
154 // SyncSendCmdError
155 bool SyncSendCmdLastError();
156
157 wxString m_LastError;
158 wxDatagramSocket *m_pMySock;
159 TSpCommandArray *m_ppCommands;
160 wxIPV4address m_ClientAddr;
161 wxIPV4address m_ServerAddr;
162 TSQueue *m_InQueue;
163 TSQueue *m_OutQueue;
164 TSClient *m_pClient;
165 bool m_Exit;
166 bool m_Error;
167 bool m_LocalCmd;
168 bool m_Timer;
169 bool m_Connected;
170 int m_Retries;
171 wxMutex *m_pMutex;
172 TSCmd *m_pCurCmd;
173 wxStopWatch m_SWTimeout;
174};
175
176#endif
diff --git a/tsheaders.h b/tsheaders.h
new file mode 100644
index 0000000..d451b8c
--- /dev/null
+++ b/tsheaders.h
@@ -0,0 +1,62 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef _TSDAEMON_H
20#define _TSDAEMON_H
21
22#include <wx/dynarray.h>
23#include <wx/thread.h>
24
25// Forward class declarations
26class TSClient;
27class TSCommand;
28class TSConnectionThread;
29class TSServer;
30class TSChannel;
31class TSPlayer;
32//only for internal use
33struct TSCmd;
34
35//define ARRAY_PTR
36//equivalent to stl::vector<TSPlayer*>
37WX_DEFINE_ARRAY_PTR(TSPlayer*, TSpPlayerArray);
38
39//define ARRAY_PTR
40//equivalent to stl::vector<TSChannel*>
41WX_DEFINE_ARRAY_PTR(TSChannel*, TSpChannelArray);
42
43//define ARRAY_PTR
44//equivalent to stl::vector<TSCommand*>
45WX_DEFINE_ARRAY_PTR(TSCommand*, TSpCommandArray);
46
47#if SIZEOF_INT == 4
48# define TS_NUM_MAX UINT_MAX
49#elif SIZEOF_INT == 2
50# define TS_NUM_MAX ULONG_MAX
51#else
52# error "No 32bit int type on this platform"
53#endif
54
55// Include classes, for declarations
56#include "tschannel.h"
57#include "tsclient.h"
58#include "tscommand.h"
59#include "tsconnectionthread.h"
60#include "tsplayer.h"
61
62#endif
diff --git a/tsplayer.cpp b/tsplayer.cpp
new file mode 100644
index 0000000..268adfc
--- /dev/null
+++ b/tsplayer.cpp
@@ -0,0 +1,200 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tsplayer.h"
21
22//Libraries
23#include <wx/txtstrm.h>
24
25IMPLEMENT_CLASS(TSPlayer, wxObject)
26
27//------------------------------------------------------------------------------
28//Default CTor, Initializes the object.
29TSPlayer::TSPlayer()
30{
31 m_Id = 0;
32 m_Flags = 0;
33 m_Privileges = 0;
34 m_ChannelId = 0;
35 m_ChannelPrivileges = 0;
36 m_Anonymous = true;
37 m_ServerAssingnsNickname = false;
38}
39
40//------------------------------------------------------------------------------
41//Default DTor.
42TSPlayer::~TSPlayer()
43{
44}
45
46//------------------------------------------------------------------------------
47// Sets the player id.
48bool TSPlayer::SetId(wxUint32 const id)
49{
50 m_Id = id;
51 return true;
52}
53
54//------------------------------------------------------------------------------
55// Sets the player channel Id.
56bool TSPlayer::SetChannelId(wxUint32 const id)
57{
58 m_ChannelId = id;
59 return true;
60}
61
62//------------------------------------------------------------------------------
63// Sets the player flags.
64bool TSPlayer::SetFlags(wxUint16 const flags)
65{
66 m_Flags = flags;
67 return true;
68}
69
70//------------------------------------------------------------------------------
71// Sets the player privileges.
72bool TSPlayer::SetPrivileges(wxUint16 const privs)
73{
74 m_Privileges = privs;
75 return true;
76}
77
78//------------------------------------------------------------------------------
79// Sets the channel privileges.
80bool TSPlayer::SetChannelPrivileges(wxUint16 const privs)
81{
82 m_ChannelPrivileges = privs;
83 return true;
84}
85
86//------------------------------------------------------------------------------
87// Sets the player nickname.
88bool TSPlayer::SetNickname(wxString const &str)
89{
90 if(str.Length() == 0)
91 {
92 SetLastError(_T("empty string"));
93 return false;
94 }
95
96 m_Nickname = str;
97 return true;
98}
99
100//------------------------------------------------------------------------------
101// Sets the login name.
102bool TSPlayer::SetLoginName(wxString const &str)
103{
104 if(str.Length() == 0)
105 {
106 m_Anonymous = ANONYMOUS_YES;
107 return true;
108 }
109
110 m_LoginName = str;
111 m_Anonymous = ANONYMOUS_NO;
112 return true;
113}
114
115//------------------------------------------------------------------------------
116// Sets the login password.
117bool TSPlayer::SetLoginPassword(wxString const &str)
118{
119 if(str.Length() == 0)
120 {
121 SetLastError(_T("empty string"));
122 return false;
123 }
124
125 m_LoginPassword = str;
126 return true;
127}
128
129//------------------------------------------------------------------------------
130// Sets the default channel.
131bool TSPlayer::SetDefaultChannel(wxString const &str)
132{
133 if(str.Length() == 0)
134 {
135 SetLastError(_T("empty string"));
136 return false;
137 }
138
139 m_DefaultChannel = str;
140 return true;
141}
142
143//------------------------------------------------------------------------------
144// Sets the default subchannel.
145 bool TSPlayer::SetDefaultSubchannel(wxString const &str)
146{
147 if(str.Length() == 0)
148 {
149 SetLastError(_T("empty string"));
150 return false;
151 }
152
153 m_DefaultSubchannel = str;
154 return true;
155}
156
157//------------------------------------------------------------------------------
158// Sets the default channel password.
159bool TSPlayer::SetDefaultChannelPassword(wxString const &str)
160{
161 if(str.Length() == 0)
162 {
163 SetLastError(_T("empty string"));
164 return false;
165 }
166
167 m_DefaultChannelPassword = str;
168 return true;
169}
170
171//------------------------------------------------------------------------------
172// Dumps object.
173void TSPlayer::Dump(wxOutputStream &ostrm) const
174{
175 wxTextOutputStream out(ostrm);
176 out << _T("Object: TSPlayer (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl;
177 out << _T("-wxUint32 m_Id: ") << wxString::Format(_T("0x%X"), m_Id) << endl;
178 out << _T("-wxUint16 m_Flags: ") << wxString::Format(_T("0x%X"), m_Flags) << endl;
179 out << _T("-wxUint16 m_Privileges: ") << wxString::Format(_T("0x%X"), m_Privileges) << endl;
180 out << _T("-wxUint32 m_ChannelId: ") << wxString::Format(_T("0x%X"), m_ChannelId) << endl;
181 out << _T("-wxUint16 m_ChannelPrivileges: ") << wxString::Format(_T("0x%X"), m_ChannelPrivileges) << endl;
182 out << _T("-wxString m_Nickname: ") << m_Nickname << endl;
183 out << _T("-wxString m_LoginName: ") << m_LoginName << endl;
184 out << _T("-wxString m_LoginPassword: ") << m_LoginPassword << endl;
185 out << _T("-wxString m_DefaultChannel: ") << m_DefaultChannel << endl;
186 out << _T("-wxString m_DefaultSubchannel: ") << m_DefaultSubchannel << endl;
187 out << _T("-wxString m_DefaultChannelPassword: ") << m_DefaultChannelPassword << endl;
188 out << _T("-wxUint8 m_Anonymous: ") << wxString::Format(_T("0x%X"), m_Anonymous) << endl;
189 out << _T("-wxUint8 m_ServerAssingnsNickname: ") << wxString::Format(_T("0x%X"), m_ServerAssingnsNickname) << endl;
190 out << _T("-wxString m_LastError: ") << m_LastError << endl;
191}
192
193//------------------------------------------------------------------------------
194// Should the server assing a nickname.
195bool TSPlayer::SetServerAssingnsNickname(wxUint8 const assing)
196{
197 m_ServerAssingnsNickname = assing;
198 return true;
199}
200
diff --git a/tsplayer.h b/tsplayer.h
new file mode 100644
index 0000000..84daa9b
--- /dev/null
+++ b/tsplayer.h
@@ -0,0 +1,339 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef TSPLAYER_H
20#define TSPLAYER_H
21
22#include "tsheaders.h"
23
24//Libraries
25#include <wx/wx.h>
26#include <wx/dynarray.h>
27
28//------------------------------------------------------------------------------
29// Player flags
30//! Channel Commander
31#define TS_CHANNEL_COMMANDER 1
32//! Voice Request
33#define TS_VOICE_REQUEST 2
34//! Doesnt Accept Whispers
35#define TS_DOESNT_ACCEPT_WHISPER 4
36//! Away
37#define TS_AWAY 8
38//! Microphone Muted
39#define TS_MICROPHONE_MUTED 16
40//! Sound Muted
41#define TS_SOUND_MUTED 32
42//! Recording
43#define TS_RECORDING 64
44
45//------------------------------------------------------------------------------
46//! Player privileges
47//! SA server admin
48#define TS_SERVER_ADMIN 1
49//! Allow Registration
50#define TS_ALLOW_REGISTRATION 2
51//! Registered
52#define TS_REGISTERED 4
53//! Internal Use
54#define TS_INTERNAL_USE 8
55//! Stickey
56#define TS_STICKY 16
57
58//------------------------------------------------------------------------------
59//! Channel privileges
60//! Channel Admin
61#define TS_CHANNEL_ADMIN 1
62//! Operator
63#define TS_OPERATOR 2
64//! Voice
65#define TS_VOICE 4
66//! Auto Operator
67#define TS_AUTO_OPERATOR 8
68//! Auto Voice
69#define TS_AUTO_VOICE 16
70
71//------------------------------------------------------------------------------
72//! Anonymous login
73//!
74#define ANONYMOUS_YES 1
75//!
76#define ANONYMOUS_NO 2
77
78//------------------------------------------------------------------------------
79//! Server assingns nickname
80//!
81#define SAN_YES 1
82//!
83#define SAN_NO 0
84
85//! TeamSpeak player.
86/*! TSPlayer is used to hold all player informations.
87 * After calling TSClient::Connect(), you can read
88 * out all the player attributes. These stepps are
89 * necessary to connect to a server and read all information
90 * out.
91 * - Create a TSServer object,edit and link it to the TSClient object
92 * (For more information see TSClient)
93 * - Call TSClient::Connect()
94 * - Call TSClient::GetPlayer() or GetPlayers()
95 * - Now the class is filled up with the player information
96 */
97class TSPlayer : public wxObject
98{
99 DECLARE_CLASS(TSPlayer)
100 public:
101 /*! Default CTor, Initializes the object.
102 */
103 TSPlayer();
104
105 /*! Default DTor.
106 */
107 ~TSPlayer();
108
109 /*! Sets the player Id.
110 * \param id Player Id.
111 * \return Returns false if fails, check GetLastError for details.
112 * \sa GetLastError()
113 */
114 bool SetId(wxUint32 const id);
115
116 /*! Sets the player channel Id.
117 * \param id Player channel Id.
118 * \return Returns false if fails, check GetLastError for details.
119 * \sa GetLastError()
120 */
121 bool SetChannelId(wxUint32 const id);
122
123 /*! Sets the player flags.
124 * \param flags Player flags.
125 * \return Returns false if fails, check GetLastError for details.
126 * \sa GetLastError()
127 */
128 bool SetFlags(wxUint16 const flags);
129
130 /*! Sets the player privileges.
131 * \param privs Player privileges.
132 * \return Returns false if fails, check GetLastError for details.
133 * \sa GetLastError()
134 */
135 bool SetPrivileges(wxUint16 const privs);
136
137 /*! Sets the channel privileges.
138 * \param privs Channel privileges.
139 * \return Returns false if fails, check GetLastError for details.
140 * \sa GetLastError()
141 */
142 bool SetChannelPrivileges(wxUint16 const privs);
143
144 /*! Sets the player nickname.
145 * \param str Player nickname.
146 * \return Returns false if fails, check GetLastError for details.
147 * \sa GetLastError()
148 */
149 bool SetNickname(wxString const &str);
150
151 /*! Sets the login name.
152 * If called with an empty string, Anonymous login is enabled,
153 * which is also default. Else Anonymous login is disabled.
154 * \param str Login name.
155 * \return Returns false if fails, check GetLastError for details.
156 * \sa GetLastError()
157 */
158 bool SetLoginName(wxString const &str);
159
160 /*! Sets the login password.
161 * \param str Login password.
162 * \return Returns false if fails, check GetLastError for details.
163 * \sa GetLastError()
164 */
165 bool SetLoginPassword(wxString const &str);
166
167 /*! Sets the default channel.
168 * \param str Default channel.
169 * \return Returns false if fails, check GetLastError for details.
170 * \sa GetLastError()
171 */
172 bool SetDefaultChannel(wxString const &str);
173
174 /*! Sets the default subchannel.
175 * \param str Default subchannel.
176 * \return Returns false if fails, check GetLastError for details.
177 * \sa GetLastError()
178 */
179 bool SetDefaultSubchannel(wxString const &str);
180
181 /*! Sets the default channel password.
182 * \param str Default channel password.
183 * \return Returns false if fails, check GetLastError for details.
184 * \sa GetLastError()
185 */
186 bool SetDefaultChannelPassword(wxString const &str);
187
188 /*! Should the server assing a nickname.
189 * - no: 0
190 * - yes: 1
191 * \param assing Server assing a nickname.
192 * \return Returns false if fails, check GetLastError for details.
193 * \sa GetLastError()
194 */
195 bool SetServerAssingnsNickname(wxUint8 const assing);
196
197 /*! Gets the player Id.
198 * \return Player Id.
199 */
200 wxUint32 GetId() const
201 {
202 return m_Id;
203 }
204
205 /*! Gets the player flags.
206 * \return Player flags.
207 */
208 wxUint32 GetFlags() const
209 {
210 return m_Flags;
211 }
212
213 /*! Gets the player privileges.
214 * \return Player privileges.
215 */
216 wxUint32 GetPrivileges() const
217 {
218 return m_Privileges;
219 }
220
221 /*! Gets the channel Id.
222 * \return Channel Id.
223 */
224 wxUint32 GetChannelId() const
225 {
226 return m_ChannelId;
227 }
228
229 /*! Gets the channel privileges.
230 * \return Channel privileges.
231 */
232 wxUint32 GetChannelPrivileges() const
233 {
234 return m_ChannelPrivileges;
235 }
236
237 /*! Gets the player nickname.
238 * \return Player nickname.
239 */
240 wxString const &GetNickname() const
241 {
242 return m_Nickname;
243 }
244
245 /*! Gets the player login name.
246 * \return Player login name.
247 */
248 wxString const &GetLoginName() const
249 {
250 return m_LoginName;
251 }
252
253 /*! Gets the player login password.
254 * \return Player login password.
255 */
256 wxString const &GetLoginPassword() const
257 {
258 return m_LoginPassword;
259 }
260
261 /*! Gets the player default channel.
262 * \return Player default channel.
263 */
264 wxString const &GetDefaultChannel() const
265 {
266 return m_DefaultChannel;
267 }
268
269 /*! Gets the player default sub channel.
270 * \return Player default sub channel.
271 */
272 wxString const &GetDefaultSubchannel() const
273 {
274 return m_DefaultSubchannel;
275 }
276
277 /*! Gets the player default channel password.
278 * \return Player default channel password.
279 */
280 wxString const &GetDefaultChannelPassword() const
281 {
282 return m_DefaultChannelPassword;
283 }
284
285 /*! Gets the player server assingns nickname status.
286 * \return Player ServerAssingnsNickname.
287 */
288 wxUint8 GetServerAssingnsNickname() const
289 {
290 return m_ServerAssingnsNickname;
291 }
292
293 /*! Gets the player anonymous login status.
294 * \return Player default channel password.
295 */
296 wxUint8 GetAnonymous() const
297 {
298 return m_Anonymous;
299 }
300
301 /*! Dumps object.
302 * \param ostrm Stream to write.
303 */
304 void Dump(wxOutputStream &ostrm) const;
305
306 /*! Gets the LastError message, call this method
307 * to get more information for an error.
308 * \return LastError message.
309 */
310 wxString const &GetLastError() const
311 {
312 return m_LastError;
313 }
314
315 private:
316 //Sets the LastError message.
317 void SetLastError(wxString const &str)
318 {
319 m_LastError = str;
320 }
321
322 //members
323 wxUint32 m_Id;
324 wxUint16 m_Flags;
325 wxUint16 m_Privileges;
326 wxUint32 m_ChannelId;
327 wxUint16 m_ChannelPrivileges;
328 wxString m_Nickname;
329 wxString m_LoginName;
330 wxString m_LoginPassword;
331 wxString m_DefaultChannel;
332 wxString m_DefaultSubchannel;
333 wxString m_DefaultChannelPassword;
334 wxString m_LastError;
335 wxUint8 m_Anonymous;
336 wxUint8 m_ServerAssingnsNickname;
337};
338
339#endif
diff --git a/tsquerythread.cpp b/tsquerythread.cpp
new file mode 100644
index 0000000..94a1fef
--- /dev/null
+++ b/tsquerythread.cpp
@@ -0,0 +1,1105 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tsquerythread.h"
21#include "wxbufferex.h"
22#include "base64.h"
23
24//Libraries
25#include <wx/wfstream.h>
26#include <wx/stream.h>
27#include <wx/sstream.h>
28#include <wx/socket.h>
29#include <wx/mstream.h>
30#include <wx/buffer.h>
31#include <wx/sckstrm.h>
32#include <wx/utils.h>
33#include <wx/memory.h>
34#include <wx/txtstrm.h>
35#include <wx/wfstream.h>
36#include <wx/txtstrm.h>
37#include <wx/tokenzr.h>
38#include <wx/strconv.h>
39
40IMPLEMENT_CLASS(TSQueryThread, wxObject)
41
42//------------------------------------------------------------------------------
43static bool strToChannelId(wxString &str, wxUint32 *pid,
44 bool pid_allowed = true)
45{
46 unsigned long l;
47 if (!str.ToULong(&l))
48 return false;
49 if (l == ULONG_MAX)
50 l = TS_NO_PARENT;
51 if (l > TS_NO_PARENT || (!pid_allowed && l == TS_NO_PARENT))
52 return false;
53 *pid = wxUint32(l);
54 return true;
55}
56
57static bool strToNum(wxString &str, wxUint32 *val)
58{
59 unsigned long l;
60 if (!str.ToULong(&l))
61 return false;
62 if (l > TS_NUM_MAX)
63 return false;
64 *val = wxUint32(l);
65 return true;
66}
67
68//------------------------------------------------------------------------------
69// thread execution starts here
70wxThread::ExitCode TSQueryThread::Entry()
71{
72 wxLogMessage(_T("TSQuery: thread started."));
73
74 // init libxml2 library
75 wxXml2::Init();
76
77 //check for bind
78 if(m_ServerAddress.Length() < 7 || m_ServerAddress == _T("0.0.0.0"))
79 m_ServerAddr.AnyAddress();
80 else
81 m_ServerAddr.Hostname(m_ServerAddress);
82
83 m_ServerAddr.Service(m_Port);
84 m_pSocket = new wxSocketServer(m_ServerAddr, wxSOCKET_REUSEADDR);
85
86 //Check socket
87 if(!m_pSocket->Ok())
88 {
89 if(m_pSocket->LastError() == wxSOCKET_INVPORT)
90 SetLastError(_T("Socket port in use"));
91 else
92 SetLastError(_T("Socket error"));
93 m_pSocket->Destroy();
94 m_pSocket = NULL;
95 return wxThread::ExitCode(EXIT_FAILURE);
96 }
97
98 while(1)
99 {
100 if (!Accept())
101 wxLogError(_T("TSQuery: %s"), m_LastError.c_str());
102 if (m_pSocket == NULL)
103 break;
104 }
105
106 return wxThread::ExitCode(EXIT_SUCCESS);
107}
108
109//------------------------------------------------------------------------------
110// and stops here
111void TSQueryThread::OnExit()
112{
113 wxLogDebug(_T("TSQuery: thread terminated."));
114
115 // cleanup libxml2 statics
116 wxXml2::Cleanup();
117
118 if(m_pSocket != NULL)
119 {
120 m_pSocket->Destroy();
121 m_pSocket = NULL;
122 }
123}
124
125//------------------------------------------------------------------------------
126// Default CTor, Initializes the object.
127TSQueryThread::TSQueryThread(TSClient *client) : wxThread(wxTHREAD_JOINABLE)
128{
129 Create();
130 //create all objects
131 //m_pSocket = new wxSocketServer(m_ServerAddr, wxSOCKET_REUSEADDR);
132 m_pClient = client;
133 m_Password = _T("");
134}
135
136//------------------------------------------------------------------------------
137// Default DTor.
138TSQueryThread::~TSQueryThread()
139{
140 //use OnExit()
141}
142
143//------------------------------------------------------------------------------
144// Listen
145bool TSQueryThread::Accept()
146{
147 //Wait until someone connect (NOTE: wxWidgets has an internal select timeout (~10 mins))
148 wxSocketBase *sock = m_pSocket->Accept();
149
150 // wxSocketBase doesn't set Error() to true after socket timeout, so we check against null
151 if(m_pSocket->LastError() == wxSOCKET_TIMEDOUT && sock == NULL)
152 return true;
153
154 // real check against null
155 if(sock == NULL)
156 {
157 SetLastError(_T("Socket, something really bad happend"));
158 m_pSocket->Destroy();
159 m_pSocket = NULL;
160 return false;
161 }
162
163 //Check if IP is allowed
164 wxIPV4address peeraddr;
165 sock->GetPeer(peeraddr);
166
167 wxLogMessage(_T("TSQuery: incoming request from %s"), peeraddr.IPAddress().c_str());
168
169 if(!IsIPAllowed(peeraddr.IPAddress()))
170 {
171 wxLogError(_T("TSQuery: %s"),GetLastError().c_str());
172 sock->Destroy();
173 return false;
174 }
175
176 //now receive
177 wxMemoryBufferEx buf(1024);
178 sock->Read(buf.GetData(), 1024);
179 buf.SetDataLen(sock->LastCount());
180 wxMemoryInputStream in(buf.GetData(), buf.GetDataLen());
181
182 wxStringOutputStream strm;
183 buf.HexDump(strm);
184 wxLogDebug(_T("TSQuery: command received:\n%s"), strm.GetString().c_str());
185
186 //Check socket
187 if(sock->LastCount() == 0)
188 {
189 SetLastError(_T("Socket, no data available"));
190 sock->Destroy();
191 return false;
192 }
193
194 //Check XML format
195 wxString err;
196 if (!m_pXml.Load(in, &err))
197 {
198 wxLogError(_T("XML format error: %s"), err.c_str());
199 return false;
200 }
201
202 //check node format
203 if(!IsValidFormat())
204 {
205 SendError(_T("General"), GetLastError(), sock);
206 sock->Destroy();
207 return false;
208 }
209
210 //check password
211 wxXml2Node pNode = m_pXml.GetRoot().Get(_T("Password")).GetFirstChild();
212 if(pNode.GetContent() != m_Password)
213 {
214 pNode = m_pXml.GetRoot().Get(_T("Command")).GetFirstChild();
215 SetLastError(_T("Invalid password"));
216 SendError(pNode.GetContent(), GetLastError(), sock);
217 sock->Destroy();
218 return false;
219 }
220
221 //check if TSClient is connected
222 if(!m_pClient->IsConnected())
223 {
224 pNode = m_pXml.GetRoot().Get(_T("Command")).GetFirstChild();
225 SetLastError(_T("No connection to TSServer"));
226 SendError(pNode.GetContent(), GetLastError(), sock);
227 sock->Destroy();
228 return false;
229 }
230
231 //ok now process the command
232 if(!ProcessCommand(sock))
233 {
234 sock->Destroy();
235 return false;
236 }
237
238 sock->Destroy();
239 wxLogMessage(_T("TSQuery: request successfully processed."));
240 return true;
241}
242
243//------------------------------------------------------------------------------
244// IsIPAllowed
245bool TSQueryThread::IsIPAllowed(wxString const &str)
246{
247 wxStringTokenizer tkz(m_AllowedAddresses, _T(","));
248 bool found = false;
249 while(tkz.HasMoreTokens())
250 {
251 wxString token = tkz.GetNextToken();
252 wxIPV4address tmpaddr;
253 if(!tmpaddr.Hostname(token))
254 {
255 SetLastError(wxString::Format(_T("'%s' this is no valid IP"),token.c_str()));
256 return false;
257 }
258 unsigned ip1[4], ip2[4];
259 if(tmpaddr.IPAddress() == str)
260 {
261 found = true;
262 break;
263 }
264 //dirty C
265 else if(wxSscanf(tmpaddr.IPAddress().c_str(), _T("%u.%u.%u.%u"), &ip1[0], &ip1[1], &ip1[2], &ip1[3]) == 4 &&
266 wxSscanf(str.c_str(), _T("%u.%u.%u.%u"), &ip2[0], &ip2[1], &ip2[2], &ip2[3]) == 4)
267 {
268 if((ip1[0] == 0 && ip1[1] == 0 && ip1[2] == 0 && ip1[3] == 0) || //0.0.0.0
269 (ip1[0] == ip2[0] && ip1[1] == 0 && ip1[2] == 0 && ip1[3] == 0) || //x.0.0.0
270 (ip1[0] == ip2[0] && ip1[1] == ip2[1] && ip1[2] == 0 && ip1[3] == 0) || //x.x.0.0
271 (ip1[0] == ip2[0] && ip1[1] == ip2[1] && ip1[2] == ip2[2] && ip1[3] == 0)) //x.x.x.0
272 {
273 found = true;
274 break;
275 }
276 }
277 }
278 if (!found)
279 {
280 SetLastError(_T("IP is not allowed"));
281 return false;
282 }
283 return true;
284}
285
286//------------------------------------------------------------------------------
287// IsValidFormat
288bool TSQueryThread::IsValidFormat()
289{
290 //check node
291 wxXml2Node pNodeRoot = m_pXml.GetRoot();
292 if(pNodeRoot.GetName() != _T("TSClient"))
293 {
294 SetLastError(_T("No 'TSClient' node found"));
295 return false;
296 }
297
298 //check node
299 wxXml2Node pNode = pNodeRoot.Get(_T("Password"));
300 if(pNode == wxXml2EmptyNode)
301 {
302 SetLastError(_T("No 'Password' node found"));
303 return false;
304 }
305
306 pNode = pNodeRoot.Get(_T("Command"));
307 if(pNode == wxXml2EmptyNode)
308 {
309 SetLastError(_T("No 'Command' node found"));
310 return false;
311 }
312
313 return true;
314}
315
316
317//------------------------------------------------------------------------------
318// ProcessCommand.
319bool TSQueryThread::ProcessCommand(wxSocketBase *sock)
320{
321 wxXml2Node pNodeRoot = m_pXml.GetRoot();
322 //check node
323 wxXml2Node pNode = pNodeRoot.Get(_T("Command"));
324 if(pNode == wxXml2EmptyNode)
325 {
326 SetLastError(_T("No 'Command' node found"));
327 SendError(_T("General"), GetLastError(), sock);
328 return false;
329 }
330
331 wxString cmd = pNode.GetFirstChild().GetContent();
332 wxLogMessage(_T("TSQuery: command '%s' received"), cmd.c_str());
333
334 pNode = pNodeRoot.Get(_T("Text"));
335 if(pNode != wxXml2EmptyNode)
336 wxLogMessage(_T("TSQuery: Text: '%s'"), pNode.GetFirstChild().GetContent().c_str());
337
338 if(cmd == _T("GetStatus"))
339 return CmdGetStatus(sock);
340 else if(cmd == _T("GetChannels"))
341 return CmdGetChannels(sock);
342 else if(cmd == _T("GetUsers"))
343 return CmdGetUsers(sock);
344 else if(cmd == _T("CreateChannel"))
345 return CmdCreateChannel(sock);
346 else if(cmd == _T("DeleteChannel"))
347 return CmdDeleteChannel(sock);
348 else if(cmd == _T("ModifyChannel"))
349 return CmdModifyChannel(sock);
350 else if(cmd == _T("MoveUser"))
351 return CmdMoveUser(sock);
352 else if(cmd == _T("KickUser"))
353 return CmdKickUser(sock);
354 else if(cmd == _T("Kill"))
355 return CmdKill(sock);
356
357 SetLastError(_T("Unknown command"));
358 SendError(cmd, GetLastError(), sock);
359 return false;
360}
361
362//------------------------------------------------------------------------------
363// SendError.
364bool TSQueryThread::SendError(wxString const &cmd, wxString const &str, wxSocketBase *sock)
365{
366 wxSocketOutputStream so(*sock);
367 wxBufferedOutputStream out(so);
368
369 m_pXml.Create(_T("1.0"));
370 wxXml2Node pNodeRoot;
371 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
372
373 wxXml2Node pNode;
374 pNode = pNodeRoot.AddTextChild(_T("Command"), cmd);
375 pNode.AddProperty(_T("State"), _T("Error"));
376
377 pNode = pNodeRoot.AddTextChild(_T("ErrorText"), str);
378
379 if(!SendDOM(sock))
380 return false;
381 return true;
382}
383
384//------------------------------------------------------------------------------
385// Dumps object.
386void TSQueryThread::Dump(wxOutputStream &ostrm) const
387{
388 wxTextOutputStream out(ostrm);
389 out << wxString(_T("-"), 60) << endl;
390 out << _T("Object: TSQueryThread (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl;
391}
392
393//------------------------------------------------------------------------------
394bool TSQueryThread::SendDOM(wxSocketBase *sock)
395{
396 wxSocketOutputStream so(*sock);
397 wxBufferedOutputStream out(so);
398 if(!m_pXml.Save(out, _T("utf-8"), wxXML2DOC_USE_NATIVE_NEWLINES | wxXML2DOC_USE_INDENTATION, 2))
399 {
400 SetLastError(_T("DOM serialization"));
401 return false;
402 }
403 out.Sync();
404 return true;
405}
406
407//------------------------------------------------------------------------------
408wxString TSQueryThread::GetNodeValue(wxXml2Node &pElemRoot, wxString const &str)
409{
410 wxXml2Node pElem = pElemRoot.Get(str);
411 if(pElem == wxXml2EmptyNode)
412 return _T("");
413 else
414 return pElem.GetFirstChild().GetContent();
415}
416
417//------------------------------------------------------------------------------
418bool TSQueryThread::CmdGetStatus(wxSocketBase *sock)
419{
420 wxString str;
421 str = wxString::Format(_T("%s:%d"), m_pClient->GetServer()->GetServerAddress().c_str(),
422 m_pClient->GetServer()->GetPort());
423
424 if(!m_pClient->IsConnected())
425 {
426 wxLogMessage(_T("TSQuery: TSServer %s is not connected"), str.c_str());
427 SetLastError(_T("No connection to TSServer"));
428 SendError(_T("GetStatus"), GetLastError(), sock);
429 return false;
430 }
431
432 m_pXml.Create(_T("1.0"));
433 wxXml2Node pNodeRoot;
434 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
435
436 wxXml2Node pNode;
437 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("GetStatus"));
438 pNode.AddProperty(_T("State"), _T("Ok"));
439
440 pNode = pNodeRoot.AddTextChild(_T("TSServer"), str);
441
442 if(!SendDOM(sock))
443 return false;
444 return true;
445}
446
447//------------------------------------------------------------------------------
448bool TSQueryThread::CmdGetChannels(wxSocketBase *sock)
449{
450 wxXml2Node pNodeRoot = m_pXml.GetRoot();
451 TSpChannelArray chs;
452
453 wxXml2Node pNode = pNodeRoot.Get(_T("ChannelName"));
454 if(pNode != wxXml2EmptyNode)
455 {
456 wxString str = pNode.GetFirstChild().GetContent();
457 m_pClient->FindChannelsByName(str, &chs);
458
459 /* remove channels not matching ParentId */
460 str = pNode.GetPropVal(_T("ParentId"), wxEmptyString);
461 wxUint32 pid;
462 if (!str.empty() && strToChannelId(str, &pid))
463 {
464 for(size_t i = 0; i < chs.Count(); i++)
465 {
466 if (chs[i]->GetParent() != pid)
467 chs.RemoveAt(i);
468 }
469 }
470
471 /* add subchannels */
472 if(pNode.GetPropVal(_T("Subchannels"), _T("No")) == _T("Yes"))
473 {
474 for(size_t i = 0; i < chs.Count(); i++)
475 m_pClient->FindChannelsByParent(chs[i]->GetId(), &chs);
476 }
477 }
478
479 pNode = pNodeRoot.Get(_T("ChannelId"));
480 if(pNode != wxXml2EmptyNode)
481 {
482 wxString str = pNode.GetFirstChild().GetContent();
483 wxUint32 chlid;
484 if (strToChannelId(str, &chlid, false))
485 {
486 TSChannel *c = m_pClient->FindChannel(chlid);
487 if(c != NULL)
488 chs.Add(c);
489
490 /* remove channels not matching ParentId */
491 wxUint32 pid;
492 str = pNode.GetPropVal(_T("ParentId"), wxEmptyString);
493 if (!str.empty() && strToChannelId(str, &pid))
494 {
495 for(size_t i = 0; i < chs.Count(); i++)
496 {
497 if (chs[i]->GetParent() != pid)
498 chs.RemoveAt(i);
499 }
500 }
501
502 /* add subchannels */
503 if(pNode.GetPropVal(_T("Subchannels"), _T("No")) == _T("Yes"))
504 {
505 for(size_t i = 0; i < chs.Count(); i++)
506 m_pClient->FindChannelsByParent(chs[i]->GetId(), &chs);
507 }
508 }
509 }
510
511 pNode = pNode.Get(_T("ChannelParentId"));
512 if(pNode != wxXml2EmptyNode)
513 {
514 wxString str = pNode.GetFirstChild().GetContent();
515 wxUint32 pid;
516 if (strToChannelId(str, &pid))
517 m_pClient->FindChannelsByParent(pid, &chs);
518 }
519
520 m_pXml.Create(_T("1.0"));
521 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
522 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("GetChannels"));
523 pNode.AddProperty(_T("State"), _T("Ok"));
524
525 wxLogMessage(_T("TSQuery: sending requested channels."));
526
527 for(size_t i = 0; i < chs.Count(); i++)
528 {
529 wxXml2Node pChannelNode;
530 pChannelNode = pNodeRoot.AddContainerChild(_T("Channel"));
531 pChannelNode.AddProperty(_T("Id"), wxString::Format(_T("%d"), chs[i]->GetId()));
532 pChannelNode.AddProperty(_T("ParentId"), wxString::Format(_T("%d"), chs[i]->GetParent()));
533
534 pChannelNode.AddTextChild(_T("ChannelName"), chs[i]->GetName());
535 pChannelNode.AddTextChild(_T("ChannelTopic"), chs[i]->GetTopic());
536 pChannelNode.AddTextChild(_T("ChannelSlots"), wxString::Format(_T("%d"), chs[i]->GetMaxUsers()));
537 pChannelNode.AddTextChild(_T("ChannelPassword"), chs[i]->GetPassword());
538 pChannelNode.AddTextChild(_T("ChannelCodec"), wxString::Format(_T("%d"), chs[i]->GetCodec()));
539 const wxCharBuffer buf = chs[i]->GetDescription().mb_str(wxConvUTF8);
540 pChannelNode.AddTextChild(_T("ChannelDescription"), Base64Encode(buf, strlen(buf)));
541 pChannelNode.AddTextChild(_T("ChannelFlags"), chs[i]->GetFlagsString());
542
543 wxLogVerbose(_T("TSQuery: Channel '%s' transmitted."), chs[i]->GetName().c_str());
544 }
545
546 if(!SendDOM(sock))
547 return false;
548 return true;
549}
550
551//------------------------------------------------------------------------------
552bool TSQueryThread::CmdGetUsers(wxSocketBase *sock)
553{
554 wxXml2Node pNodeRoot = m_pXml.GetRoot();
555 TSpPlayerArray pls;
556 wxString str;
557
558 wxXml2Node pNode;
559 pNode = pNodeRoot.Get(_T("UserName"));
560 if(pNode != wxXml2EmptyNode)
561 {
562 str = pNode.GetFirstChild().GetContent();
563 m_pClient->FindPlayersByName(str, &pls);
564 }
565
566 pNode = pNodeRoot.Get(_T("UserId"));
567 if(pNode != wxXml2EmptyNode)
568 {
569 str = pNode.GetFirstChild().GetContent();
570 wxUint32 plyid;
571 if (strToNum(str, &plyid))
572 pls.Add(m_pClient->FindPlayer(plyid));
573 }
574
575 pNode = pNodeRoot.Get(_T("ChannelName"));
576 if(pNode != wxXml2EmptyNode)
577 {
578 str = pNode.GetFirstChild().GetContent();
579 TSpChannelArray chs;
580 m_pClient->FindChannelsByName(str, &chs);
581
582 /* remove channels not matching ParentId */
583 wxUint32 pid;
584 str = pNode.GetPropVal(_T("ParentId"), wxEmptyString);
585 if (!str.empty() && strToChannelId(str, &pid))
586 {
587 for(size_t i = 0; i < chs.Count(); i++)
588 {
589 if (chs[i]->GetParent() != pid)
590 chs.RemoveAt(i);
591 }
592 }
593
594 /* find users */
595 for(size_t i = 0; i < chs.Count(); i++)
596 {
597 m_pClient->FindPlayersByChannel(chs[i], &pls);
598
599 /* add subchannels and their users */
600 if (pNode.GetPropVal(_T("Subchannels"), _T("No")) == _T("Yes"))
601 {
602 TSpChannelArray chs2;
603 m_pClient->FindChannelsByParent(chs[i]->GetId(), &chs2);
604 for(size_t j = 0; j < chs2.Count(); j++)
605 m_pClient->FindPlayersByChannel(chs2[j], &pls);
606 }
607 }
608 }
609
610 pNode = pNodeRoot.Get(_T("ChannelId"));
611 if(pNode != wxXml2EmptyNode)
612 {
613 str = pNode.GetFirstChild().GetContent();
614 TSChannel *cl = NULL;
615 wxUint32 chlid;
616 if (strToChannelId(str, &chlid, false))
617 cl = m_pClient->FindChannel(chlid);
618 if (cl == NULL)
619 {
620 SetLastError(_T("Error while searching for channel."));
621 SendError(_T("GetUsers"), GetLastError(), sock);
622 return false;
623 }
624
625 m_pClient->FindPlayersByChannel(cl, &pls);
626
627 if (pNode.GetPropVal(_T("Subchannels"), _T("No")) == _T("Yes"))
628 {
629 TSpChannelArray chs;
630 m_pClient->FindChannelsByParent(cl->GetId(), &chs);
631 for(size_t i = 0; i < chs.Count(); i++)
632 m_pClient->FindPlayersByChannel(chs[i], &pls);
633 }
634 }
635
636 m_pXml.Create(_T("1.0"));
637 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
638 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("GetUsers"));
639 pNode.AddProperty(_T("State"), _T("Ok"));
640
641 wxLogMessage(_T("TSQuery: sending requested users."));
642
643 for(size_t i = 0; i < pls.Count(); i++)
644 {
645 wxXml2Node pUserNode;
646 pUserNode = pNodeRoot.AddContainerChild(_T("User"));
647 pUserNode.AddProperty(_T("Id"), wxString::Format(_T("%d"), pls[i]->GetId()));
648
649 pUserNode.AddTextChild(_T("UserName"), pls[i]->GetNickname().c_str());
650 pUserNode.AddTextChild(_T("UserChannelId"), wxString::Format(_T("%d"), pls[i]->GetChannelId()).c_str());
651 pUserNode.AddTextChild(_T("UserFlags"), wxString::Format(_T("%d"), pls[i]->GetFlags()).c_str());
652 pUserNode.AddTextChild(_T("UserPrivileges"), wxString::Format(_T("%d"), pls[i]->GetPrivileges()).c_str());
653 pUserNode.AddTextChild(_T("UserChannelPrivileges"), wxString::Format(_T("%d"), pls[i]->GetChannelPrivileges()).c_str());
654
655 wxLogVerbose(_T("TSQuery: User '%s' transmitted."), pls[i]->GetNickname().c_str());
656 }
657
658 if(!SendDOM(sock))
659 return false;
660
661 return true;
662}
663
664//------------------------------------------------------------------------------
665bool TSQueryThread::CmdCreateChannel(wxSocketBase *sock)
666{
667 wxXml2Node pNodeRoot = m_pXml.GetRoot();
668 TSChannel cl;
669 wxString str;
670
671 wxXml2Node pNode;
672 pNode = pNodeRoot.Get(_T("Channel"));
673 if(pNode == wxXml2EmptyNode)
674 {
675 SetLastError(_T("No channel node"));
676 SendError(_T("CreateChannel"), GetLastError(), sock);
677 return false;
678 }
679
680 wxUint32 chlid;
681 str = pNode.GetPropVal(_T("ParentId"), _T("-1"));
682 if (!strToChannelId(str, &chlid))
683 {
684 SetLastError(_T("Invalid parent id"));
685 SendError(_T("CreateChannel"), GetLastError(), sock);
686 return false;
687 }
688
689 cl.SetParent(chlid);
690 cl.SetName(GetNodeValue(pNode, _T("ChannelName")));
691 cl.SetTopic(GetNodeValue(pNode, _T("ChannelTopic")));
692 cl.SetPassword(GetNodeValue(pNode, _T("ChannelPassword")));
693
694 wxUint32 num;
695 str = GetNodeValue(pNode, _T("ChannelSlots"));
696 if (!strToNum(str, &num))
697 {
698 SetLastError(_T("Invalid channel slots value"));
699 SendError(_T("CreateChannel"), GetLastError(), sock);
700 return false;
701 }
702 cl.SetMaxUsers(num);
703
704 str = GetNodeValue(pNode, _T("ChannelCodec"));
705 if (!strToNum(str, &num))
706 {
707 SetLastError(_T("Invalid channel codec value"));
708 SendError(_T("CreateChannel"), GetLastError(), sock);
709 return false;
710 }
711 cl.SetCodec(num);
712
713 wxCSConv conv_iso(_T("iso-8859-1"));
714 wxString base64_encoded = GetNodeValue(pNode, _T("ChannelDescription"));
715 cl.SetDescription(wxString(Base64Decode(base64_encoded).mb_str(conv_iso), wxConvUTF8));
716 cl.SetFlags(GetNodeValue(pNode, _T("ChannelFlags")));
717
718 m_pClient->CreateChannel(&cl);
719
720 // dirty wait for channel id
721 wxUint32 channelid = 0;
722 for (wxUint32 i = 0; i <= 2; i++)
723 {
724 TSpChannelArray chs;
725 if (cl.GetParent() == TS_NO_PARENT)
726 {
727 // we wait for a main channel
728 m_pClient->FindChannelsByName(_T("^") + cl.GetName() + _T("$"), &chs);
729 for(size_t i = 0; i < chs.Count(); i++)
730 {
731 if (chs[i]->GetParent() == TS_NO_PARENT)
732 {
733 channelid = chs[i]->GetId();
734 break;
735 }
736 }
737 }
738 else
739 {
740 // we wait for a subchannel
741 m_pClient->FindChannelsByParent(cl.GetParent(), &chs);
742 for(size_t i = 0; i < chs.Count(); i++)
743 {
744 if (chs[i]->GetName() == cl.GetName())
745 {
746 channelid = chs[i]->GetId();
747 break;
748 }
749 }
750 }
751
752 if (channelid > 0)
753 break;
754 Sleep(500);
755 }
756
757 if (channelid <= 0)
758 {
759 SetLastError(_T("Error while creating channel."));
760 SendError(_T("CreateChannel"), GetLastError(), sock);
761 return false;
762 }
763
764 m_pXml.Create(_T("1.0"));
765 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
766 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("CreateChannel"));
767 pNode.AddProperty(_T("State"), _T("Ok"));
768
769 pNodeRoot.AddTextChild(_T("ChannelId"), wxString::Format(_T("%d"), channelid));
770
771 wxLogMessage(_T("TSQuery: Channel '%s' created."), cl.GetName().c_str());
772
773 if(!SendDOM(sock))
774 return false;
775
776 return true;
777}
778
779//------------------------------------------------------------------------------
780bool TSQueryThread::CmdDeleteChannel(wxSocketBase *sock)
781{
782 wxXml2Node pNodeRoot = m_pXml.GetRoot();
783 TSChannel *cl = NULL;
784 wxString str;
785
786 wxXml2Node pNode;
787 pNode = pNodeRoot.Get(_T("ChannelId"));
788 if(pNode != wxXml2EmptyNode)
789 {
790 str = pNode.GetFirstChild().GetContent();
791 wxUint32 chlid;
792 if (strToChannelId(str, &chlid, false))
793 cl = m_pClient->FindChannel(chlid);
794 }
795
796 if(cl == NULL)
797 {
798 SetLastError(_T("Channel not found."));
799 SendError(_T("DeleteChannel"), GetLastError(), sock);
800 return false;
801 }
802
803 TSChannel *defchl = m_pClient->FindDefaultChannel();
804
805 // process subchannels
806 TSpChannelArray chs;
807 m_pClient->FindChannelsByParent(cl->GetId(), &chs);
808 for(size_t i = 0; i < chs.Count(); i++)
809 {
810 TSpPlayerArray ply;
811 m_pClient->FindPlayersByChannel(chs[i], &ply);
812
813 for(size_t i=0;i<ply.GetCount();i++)
814 {
815 TSPlayer pl;
816 pl.SetId(ply.Item(i)->GetId());
817 pl.SetChannelId(defchl->GetId());
818 m_pClient->MovePlayer(&pl);
819 }
820 }
821
822 // process main channel
823 TSpPlayerArray ply;
824 m_pClient->FindPlayersByChannel(cl,&ply);
825
826 for(size_t i=0;i<ply.GetCount();i++)
827 {
828 TSPlayer pl;
829 pl.SetId(ply.Item(i)->GetId());
830 pl.SetChannelId(defchl->GetId());
831 m_pClient->MovePlayer(&pl);
832 }
833
834 wxLogMessage(_T("TSQuery: Channel '%s' deleted."),cl->GetName().c_str());
835
836 m_pClient->DeleteChannel(cl);
837
838 m_pXml.Create(_T("1.0"));
839 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
840 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("DeleteChannel"));
841 pNode.AddProperty(_T("State"), _T("Ok"));
842
843 if(!SendDOM(sock))
844 return false;
845
846 return true;
847}
848
849//------------------------------------------------------------------------------
850bool TSQueryThread::CmdModifyChannel(wxSocketBase *sock)
851{
852 wxXml2Node pNodeRoot = m_pXml.GetRoot();
853 TSChannel cl;
854 wxString str;
855
856 wxXml2Node pNode;
857 pNode = pNodeRoot.Get(_T("Channel"));
858 if(pNode == wxXml2EmptyNode)
859 {
860 SetLastError(_T("No channel node"));
861 SendError(_T("CreateChannel"), GetLastError(), sock);
862 return false;
863 }
864
865 wxUint32 chlid;
866 str = pNode.GetPropVal(_T("Id"), _T(""));
867 if (!strToChannelId(str, &chlid, false))
868 {
869 SetLastError(_T("No id attribute found"));
870 SendError(_T("CreateChannel"), GetLastError(), sock);
871 return false;
872 }
873
874 cl.SetId(chlid);
875 cl.SetName(GetNodeValue(pNode, _T("ChannelName")));
876 cl.SetTopic(GetNodeValue(pNode, _T("ChannelTopic")));
877 cl.SetPassword(GetNodeValue(pNode, _T("ChannelPassword")));
878
879 wxUint32 num;
880 str = GetNodeValue(pNode, _T("ChannelSlots"));
881 if (!strToNum(str, &num))
882 {
883 SetLastError(_T("Invalid channel slots value"));
884 SendError(_T("CreateChannel"), GetLastError(), sock);
885 return false;
886 }
887 cl.SetMaxUsers(num);
888
889 str = GetNodeValue(pNode, _T("ChannelCodec"));
890 if (!strToNum(str, &num))
891 {
892 SetLastError(_T("Invalid channel codec value"));
893 SendError(_T("CreateChannel"), GetLastError(), sock);
894 return false;
895 }
896 cl.SetCodec(num);
897
898 wxCSConv conv_iso(_T("iso-8859-1"));
899 wxString base64_encoded = GetNodeValue(pNode, _T("ChannelDescription"));
900 cl.SetDescription(wxString(Base64Decode(base64_encoded).mb_str(conv_iso), wxConvUTF8));
901 cl.SetFlags(GetNodeValue(pNode, _T("ChannelFlags")));
902
903 m_pClient->ModifyChannel(&cl);
904
905 m_pXml.Create(_T("1.0"));
906 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
907 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("ModifyChannel"));
908 pNode.AddProperty(_T("State"), _T("Ok"));
909
910 wxLogMessage(_T("TSQuery: Channel '%s' modified."), cl.GetName().c_str());
911
912 if(!SendDOM(sock))
913 return false;
914
915 return true;
916}
917
918//------------------------------------------------------------------------------
919bool TSQueryThread::CmdMoveUser(wxSocketBase *sock)
920{
921 wxXml2Node pNodeRoot = m_pXml.GetRoot();
922 TSPlayer *pl = NULL;
923 TSChannel *cl = NULL;
924 wxString str;
925
926 wxXml2Node pNode;
927 pNode = pNodeRoot.Get(_T("UserId"));
928 if(pNode != wxXml2EmptyNode)
929 {
930 str = pNode.GetFirstChild().GetContent();
931 wxUint32 plyid;
932 if (strToNum(str, &plyid))
933 pl = m_pClient->FindPlayer(plyid);
934 }
935
936 if(pl == NULL)
937 {
938 SetLastError(_T("User not found."));
939 SendError(_T("MoveUser"), GetLastError(), sock);
940 return false;
941 }
942
943 pNode = pNodeRoot.Get(_T("ChannelId"));
944 if(pNode != wxXml2EmptyNode)
945 {
946 str = pNode.GetFirstChild().GetContent();
947 wxUint32 chlid;
948 if (strToChannelId(str, &chlid, false))
949 cl = m_pClient->FindChannel(chlid);
950 }
951
952 if(cl == NULL)
953 {
954 SetLastError(_T("Channel not found."));
955 SendError(_T("MoveUser"), GetLastError(), sock);
956 return false;
957 }
958
959 pl->SetChannelId(cl->GetId());
960 m_pClient->MovePlayer(pl);
961
962 m_pXml.Create(_T("1.0"));
963 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
964 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("MoveUser"));
965 pNode.AddProperty(_T("State"), _T("Ok"));
966
967 wxLogMessage(_T("TSQuery: User '%s' moved to '%s'."), pl->GetNickname().c_str(),
968 m_pClient->FindChannel(pl->GetChannelId())->GetName().c_str());
969
970 if(!SendDOM(sock))
971 return false;
972
973 return true;
974}
975
976//------------------------------------------------------------------------------
977bool TSQueryThread::CmdKickUser(wxSocketBase *sock)
978{
979 wxXml2Node pNodeRoot = m_pXml.GetRoot();
980 TSPlayer *pl = NULL;
981 wxString str;
982
983 wxXml2Node pNode;
984 pNode = pNodeRoot.Get(_T("UserId"));
985 if(pNode != wxXml2EmptyNode)
986 {
987 str = pNode.GetFirstChild().GetContent();
988 wxUint32 plyid;
989 if (strToNum(str, &plyid))
990 pl = m_pClient->FindPlayer(plyid);
991 }
992
993 if(pl == NULL)
994 {
995 SetLastError(_T("User not found."));
996 SendError(_T("KickUser"), GetLastError(), sock);
997 return false;
998 }
999
1000 str = _T("");
1001 pNode = pNodeRoot.Get(_T("Reason"));
1002 if(pNode != wxXml2EmptyNode)
1003 str = pNode.GetFirstChild().GetContent();
1004
1005 wxLogMessage(_T("TSQuery: User '%s' kicked."), pl->GetNickname().c_str());
1006
1007 m_pClient->KickPlayer(pl, str);
1008
1009 m_pXml.Create(_T("1.0"));
1010 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
1011 pNode = pNodeRoot.AddTextChild(_T("Command"), _T("KickUser"));
1012 pNode.AddProperty(_T("State"), _T("Ok"));
1013
1014 if(!SendDOM(sock))
1015 return false;
1016
1017 return true;
1018}
1019
1020//------------------------------------------------------------------------------
1021bool TSQueryThread::CmdKill(wxSocketBase *sock)
1022{
1023 if(m_pClient->IsConnected())
1024 m_pClient->Disconnect(false);
1025
1026 wxXml2Node pNodeRoot;
1027 m_pXml.Create(_T("1.0"));
1028 pNodeRoot.CreateRoot(m_pXml, _T("TSClient"));
1029 wxXml2Node pNode = pNodeRoot.AddTextChild(_T("Command"), _T("Kill"));
1030 pNode.AddProperty(_T("State"), _T("Ok"));
1031
1032 if(!SendDOM(sock))
1033 return false;
1034
1035 return true;
1036}
1037
1038//------------------------------------------------------------------------------
1039// Sets the password for incomming connections.
1040
1041bool TSQueryThread::SetPassword(wxString const &str)
1042{
1043 if(str.Length() == 0)
1044 {
1045 SetLastError(_T("Empty string"));
1046 return false;
1047 }
1048 m_Password = str;
1049 return true;
1050}
1051
1052//------------------------------------------------------------------------------
1053// Sets the server address.
1054bool TSQueryThread::SetServerAddress(wxString const &str)
1055{
1056 if(str.Length() == 0)
1057 {
1058 SetLastError(_T("Empty string"));
1059 return false;
1060 }
1061 m_ServerAddress = str;
1062 return true;
1063}
1064
1065//------------------------------------------------------------------------------
1066// Sets the allowed address.
1067bool TSQueryThread::SetAllowedAddresses(wxString const &str)
1068{
1069 if(str.Length() == 0)
1070 {
1071 SetLastError(_T("Empty string"));
1072 return false;
1073 }
1074 m_AllowedAddresses = str;
1075 return true;
1076}
1077
1078//------------------------------------------------------------------------------
1079// Sets the connection port.
1080bool TSQueryThread::SetPort(wxUint16 const &port)
1081{
1082 if(port == 0)
1083 {
1084 SetLastError(_T("Empty port"));
1085 return false;
1086 }
1087 m_Port = port;
1088 return true;
1089}
1090
1091//------------------------------------------------------------------------------
1092// Start thread.
1093bool TSQueryThread::Start()
1094{
1095 Run();
1096 return true;
1097}
1098
1099//------------------------------------------------------------------------------
1100// Stop thread.
1101bool TSQueryThread::Stop()
1102{
1103 Kill();
1104 return true;
1105}
diff --git a/tsquerythread.h b/tsquerythread.h
new file mode 100644
index 0000000..c41c535
--- /dev/null
+++ b/tsquerythread.h
@@ -0,0 +1,184 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19//Header guard
20#ifndef TSQUERY_H
21#define TSQUERY_H
22
23//Libraries
24#include <wx/wx.h>
25#include <wx/socket.h>
26#include <wx/xml2.h>
27
28#include "tsheaders.h"
29
30//! TSQuery
31/*! TSQuery
32 */
33class TSQueryThread : public wxThread
34{
35 DECLARE_CLASS(TSQueryThread)
36 public:
37
38 /*! thread execution starts here
39 * \return Returns ExitCode.
40 */
41 virtual ExitCode Entry();
42
43 /*! and stops here
44 */
45 virtual void OnExit();
46
47 /*! Default CTor, Initializes the object.
48 * Creates all necessary member objects.
49 */
50 TSQueryThread(TSClient *client);
51
52 /*! Default DTor.
53 */
54 ~TSQueryThread();
55
56 /*! Sets the password for incomming connections.
57 * \param str Password string.
58 * \return Returns false if fails, check GetLastError for details.
59 * \sa GetLastError()
60 */
61 bool SetPassword(wxString const &str);
62
63 /*! Sets the allowed Addresses.
64 * You can use either an IP or an URL, seperate with ','
65 * \param str Server address string.
66 * \return Returns false if fails, check GetLastError for details.
67 * \sa GetLastError()
68 */
69 bool SetAllowedAddresses(wxString const &str);
70
71 /*! Start thread.
72 * \return Returns false if fails, check GetLastError for details.
73 * \sa GetLastError()
74 */
75 bool Start();
76
77 /*! Stop thread.
78 * \return Returns false if fails, check GetLastError for details.
79 * \sa GetLastError()
80 */
81 bool Stop();
82
83 /*! Sets the server address.
84 * You can use either an IP or an URL.
85 * \param str Server address string.
86 * \return Returns false if fails, check GetLastError for details.
87 * \sa GetLastError()
88 */
89 bool SetServerAddress(wxString const &str);
90
91 /*! Sets the connection port.
92 * \param port Connection port.
93 * \return Returns false if fails, check GetLastError for details.
94 * \sa GetLastError()
95 */
96 bool SetPort(wxUint16 const &port);
97
98 /*! Listen for incomming connections.
99 * \return Returns false if fails, check GetLastError for details.
100 * \sa GetLastError()
101 */
102 bool Accept();
103
104 /*! Dumps object.
105 * \param ostrm Stream to write.
106 */
107 void Dump(wxOutputStream &ostrm) const;
108
109 /*! Gets the server Address.
110 * \return Returns the current password.
111 */
112 wxString const &GetServerAddress() const
113 {
114 return m_ServerAddress;
115 }
116 /*! Gets the password for incomming connections.
117 * \return Returns the current password.
118 */
119 wxString const &GetPassword() const
120 {
121 return m_Password;
122 }
123
124 /*! Gets the allowed addresses for incomming connections.
125 * \return Returns the allowed addresses.
126 */
127 wxString const &GetAllowedAddresses() const
128 {
129 return m_AllowedAddresses;
130 }
131
132 /*! Gets the port for incomming connections.
133 * \return Returns the current port.
134 */
135 wxUint16 const &GetPort() const
136 {
137 return m_Port;
138 }
139 /*! Gets the LastError message, call this method
140 * to get more information for an error.
141 * \return LastError message.
142 */
143 wxString const &GetLastError() const
144 {
145 return m_LastError;
146 }
147
148 private:
149 bool CmdGetStatus(wxSocketBase *sock);
150 bool CmdGetChannels(wxSocketBase *sock);
151 bool CmdGetUsers(wxSocketBase *sock);
152 bool CmdCreateChannel(wxSocketBase *sock);
153 bool CmdDeleteChannel(wxSocketBase *sock);
154 bool CmdModifyChannel(wxSocketBase *sock);
155 bool CmdMoveUser(wxSocketBase *sock);
156 bool CmdKickUser(wxSocketBase *sock);
157 bool CmdKill(wxSocketBase *sock);
158
159 bool SendDOM(wxSocketBase *sock);
160 bool ProcessCommand(wxSocketBase *sock);
161 bool SendError(wxString const &cmd, wxString const &str, wxSocketBase *sock);
162 bool IsIPAllowed(wxString const &str);
163 bool IsValidFormat();
164 wxString GetNodeValue(wxXml2Node &pElemRoot, wxString const &str);
165
166 //Sets the LastError message.
167 void SetLastError(wxString const &str)
168 {
169 m_LastError = str;
170 }
171
172 //Members
173 wxString m_LastError;
174 wxString m_AllowedAddresses;
175 wxString m_Password;
176 wxSocketServer *m_pSocket;
177 wxIPV4address m_ServerAddr;
178 TSClient *m_pClient;
179 wxXml2Document m_pXml;
180 wxUint16 m_Port;
181 wxString m_ServerAddress;
182};
183
184#endif
diff --git a/tsserver.cpp b/tsserver.cpp
new file mode 100644
index 0000000..a0275d6
--- /dev/null
+++ b/tsserver.cpp
@@ -0,0 +1,168 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "tsserver.h"
21
22//Libraries
23#include <wx/txtstrm.h>
24
25IMPLEMENT_CLASS(TSServer, wxObject)
26
27//------------------------------------------------------------------------------
28//Default CTor, Initializes the object.
29TSServer::TSServer()
30{
31 m_Id = 0;
32 m_Type = 0;
33 m_Port = 0;
34 m_HostAddress = _T("localhost");
35}
36
37//------------------------------------------------------------------------------
38//Default DTor.
39TSServer::~TSServer()
40{
41}
42
43//------------------------------------------------------------------------------
44// Sets the server message.
45bool TSServer::SetServerMessage(wxString const &str)
46{
47 if(str.Length() == 0)
48 {
49 SetLastError(_T("empty string"));
50 return false;
51 }
52 m_ServerMessage = str;
53 return true;
54}
55
56//------------------------------------------------------------------------------
57// Sets the welcome message.
58bool TSServer::SetWelcomeMessage(wxString const &str)
59{
60 if(str.Length() == 0)
61 {
62 SetLastError(_T("empty string"));
63 return false;
64 }
65 m_WelcomeMessage = str;
66 return true;
67}
68
69//------------------------------------------------------------------------------
70// Sets the server message.
71bool TSServer::SetVersionNumber(wxString const &str)
72{
73 if(str.Length() == 0)
74 {
75 SetLastError(_T("empty string"));
76 return false;
77 }
78 m_VersionNumber = str;
79 return true;
80}
81
82//------------------------------------------------------------------------------
83// Sets the host address, bindes the client to an address.
84bool TSServer::SetHostAddress(wxString const &str)
85{
86 if(str.Length() == 0)
87 {
88 SetLastError(_T("empty string"));
89 return false;
90 }
91 m_HostAddress = str;
92 return true;
93}
94
95//------------------------------------------------------------------------------
96// Sets the server address.
97bool TSServer::SetServerAddress(wxString const &str)
98{
99 if(str.Length() == 0)
100 {
101 SetLastError(_T("empty string"));
102 return false;
103 }
104 m_ServerAddress = str;
105 return true;
106}
107//------------------------------------------------------------------------------
108// Sets the server Id.
109bool TSServer::SetId(wxUint32 const &id)
110{
111 m_Id = id;
112 return true;
113}
114
115//------------------------------------------------------------------------------
116// Sets the connection port.
117bool TSServer::SetPort(wxUint16 const &port)
118{
119 if(port == 0)
120 {
121 SetLastError(_T("empty port"));
122 return false;
123 }
124 m_Port = port;
125 return true;
126}
127
128//------------------------------------------------------------------------------
129// Sets the server type.
130bool TSServer::SetServerType(wxUint16 const &type)
131{
132 m_ServerType = type;
133 return true;
134}
135
136//------------------------------------------------------------------------------
137// Sets the platform string.
138bool TSServer::SetPlatform(wxString const &str)
139{
140 if(str.Length() == 0)
141 {
142 SetLastError(_T("empty string"));
143 return false;
144 }
145 m_Platform = str;
146 return true;
147}
148
149//------------------------------------------------------------------------------
150// Dumps object.
151void TSServer::Dump(wxOutputStream &ostrm) const
152{
153 wxTextOutputStream out(ostrm);
154 out << _T("Object: TSServer (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl;
155 out << _T("-wxUint32 m_Id: ") << wxString::Format(_T("0x%X"), m_Id) << endl;
156 out << _T("-wxString m_VersionNumber: ") << m_VersionNumber << endl;
157 out << _T("-wxString m_WelcomeMessage: ") << m_WelcomeMessage << endl;
158 out << _T("-wxString m_ServerMessage: ") << m_ServerMessage << endl;
159 out << _T("-wxString m_Platform: ") << m_Platform << endl;
160 out << _T("-wxUint32 m_Type: ") << wxString::Format(_T("0x%X"), m_Type) << endl;
161 out << _T("-wxString m_ISPLinkURL: ") << m_ISPLinkURL << endl;
162 out << _T("-wxString m_ServerAddress: ") << m_ServerAddress << endl;
163 out << _T("-wxString m_HostAddress: ") << m_HostAddress << endl;
164 out << _T("-wxUint16 m_Port: ") << wxString::Format(_T("0x%X"), m_Port) << endl;
165 out << _T("-wxUint16 m_ServerType: ") << wxString::Format(_T("0x%X"), m_ServerType) << endl;
166 out << _T("-wxString m_LastError: ") << m_LastError << endl;
167}
168
diff --git a/tsserver.h b/tsserver.h
new file mode 100644
index 0000000..dc3b1fd
--- /dev/null
+++ b/tsserver.h
@@ -0,0 +1,243 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef TSSERVER_H
20#define TSSERVER_H
21
22// Libraries
23#include <wx/wx.h>
24
25//------------------------------------------------------------------------------
26// Server flags
27#define TS_SERVER_CLAN 5
28#define TS_SERVER_PUBLIC 6
29
30//! TeamSpeak server.
31/*! TSServer is used to hold all server informations.
32 * After calling TSClient::Connect(), you can read
33 * out all the servers attributes. These stepps are
34 * necessary to connect to a server and read all information
35 * out.
36 * - Create a TSServer object,edit and link it to the TSClient object
37 * (For more information see TSClient)
38 * - Call TSClient::Connect()
39 * - Call TSClient::GetServer()
40 * - Now the class is filled up with the server information
41 */
42class TSServer : public wxObject
43{
44 DECLARE_CLASS(TSServer)
45 public:
46 /*! Default CTor, Initializes the object.
47 */
48 TSServer();
49
50 /*! Default DTor.
51 */
52 ~TSServer();
53
54 /*! Sets the server message.
55 * \param str Server message string.
56 * \return Returns false if fails, check GetLastError for details.
57 * \sa GetLastError()
58 */
59 bool SetServerMessage(wxString const &str);
60
61 /*! Sets the welcome message.
62 * \param str Welcome message string.
63 * \return Returns false if fails, check GetLastError for details.
64 * \sa GetLastError()
65 */
66 bool SetWelcomeMessage(wxString const &str);
67
68 /*! Sets the platform string.
69 * \param str Platform string.
70 * \return Returns false if fails, check GetLastError for details.
71 * \sa GetLastError()
72 */
73 bool SetPlatform(wxString const &str);
74
75 /*! Sets the server message.
76 * \param str Server message string.
77 * \return Returns false if fails, check GetLastError for details.
78 * \sa GetLastError()
79 */
80 bool SetVersionNumber(wxString const &str);
81
82 /*! Sets the host address, bindes the client to an address.
83 * You can use either an IP or an URL.
84 * \param str Host address string.
85 * \return Returns false if fails, check GetLastError for details.
86 * \sa GetLastError()
87 */
88 bool SetHostAddress(wxString const &str);
89
90 /*! Sets the server address.
91 * You can use either an IP or an URL.
92 * \param str Server address string.
93 * \return Returns false if fails, check GetLastError for details.
94 * \sa GetLastError()
95 */
96 bool SetServerAddress(wxString const &str);
97
98 /*! Sets the server Id.
99 * \param id Server Id.
100 * \return Returns false if fails, check GetLastError for details.
101 * \sa GetLastError()
102 */
103 bool SetId(wxUint32 const &id);
104
105 /*! Sets the connection port.
106 * \param port Connection port.
107 * \return Returns false if fails, check GetLastError for details.
108 * \sa GetLastError()
109 */
110 bool SetPort(wxUint16 const &port);
111
112 /*! Sets the server type
113 * \param type Server type.
114 * \return Returns false if fails, check GetLastError for details.
115 * \sa GetLastError()
116 */
117 bool SetServerType(wxUint16 const &type);
118
119 /*! Gets the server Id.
120 * \return server Id.
121 */
122 wxUint32 GetId() const
123 {
124 return m_Id;
125 }
126
127 /*! Gets the server port.
128 * \return server port.
129 */
130 wxUint16 GetPort() const
131 {
132 return m_Port;
133 }
134
135 /*! Gets the server type.
136 * \return server type.
137 */
138 wxUint32 GetType() const
139 {
140 return m_Type;
141 }
142
143 /*! Gets the server version number.
144 * \return server version number.
145 */
146 wxString const &GetVersionNumber() const
147 {
148 return m_VersionNumber;
149 }
150
151 /*! Gets the server welcome message.
152 * \return server welcome message.
153 */
154 wxString const &GetWelcomeMessage() const
155 {
156 return m_WelcomeMessage;
157 }
158
159 /*! Gets the server server message.
160 * \return server server message.
161 */
162 wxString const &GetServerMessage() const
163 {
164 return m_ServerMessage;
165 }
166
167 /*! Gets the server platform.
168 * \return server platform.
169 */
170 wxString const &GetPlatform() const
171 {
172 return m_Platform;
173 }
174
175 /*! Gets the server ISPLinkURL.
176 * \return server ISPLinkURL.
177 */
178 wxString const &GetISPLinkURL() const
179 {
180 return m_ISPLinkURL;
181 }
182
183 /*! Gets the server address.
184 * \return server address.
185 */
186 wxString const &GetServerAddress() const
187 {
188 return m_ServerAddress;
189 }
190
191 /*! Gets the host address.
192 * \return host address.
193 */
194 wxString const &GetHostAddress() const
195 {
196 return m_HostAddress;
197 }
198
199 /*! Gets the server type.
200 * \return server type.
201 */
202 wxUint16 const &GetServerType() const
203 {
204 return m_ServerType;
205 }
206
207 /*! Dumps object.
208 * \param ostrm Stream to write.
209 */
210 void Dump(wxOutputStream &ostrm) const;
211
212 /*! Gets the LastError message, call this method
213 * to get more information for an error.
214 * \return LastError message.
215 */
216 wxString const &GetLastError() const
217 {
218 return m_LastError;
219 }
220
221 private:
222 //Sets the LastError message.
223 void SetLastError(wxString const &str)
224 {
225 m_LastError = str;
226 }
227
228 //members
229 wxUint32 m_Id;
230 wxString m_VersionNumber;
231 wxString m_WelcomeMessage;
232 wxString m_ServerMessage;
233 wxString m_Platform;
234 wxUint32 m_Type;
235 wxString m_ISPLinkURL;
236 wxString m_ServerAddress;
237 wxString m_HostAddress;
238 wxString m_LastError;
239 wxUint16 m_Port;
240 wxUint16 m_ServerType;
241};
242
243#endif
diff --git a/wxbufferex.cpp b/wxbufferex.cpp
new file mode 100644
index 0000000..78bd167
--- /dev/null
+++ b/wxbufferex.cpp
@@ -0,0 +1,80 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "wxbufferex.h"
21
22//Libraries
23#include <wx/txtstrm.h>
24
25//------------------------------------------------------------------------------
26// Hex dump on the stream.
27void wxMemoryBufferEx::HexDump(wxOutputStream &strm)
28{
29 wxTextOutputStream out(strm);
30 const size_t colums = 16;
31 size_t size = GetDataLen();
32
33 //print all data
34 for(size_t i = 0; i < ((size % colums == 0) ? (size / colums) : (size / colums) + 1); i++)
35 {
36 //address
37 out << wxString::Format(_T("%.4x "), i * colums);
38
39 //print hex table
40 for(size_t j = 0; j < colums; j++)
41 {
42 if(j == colums/2)
43 out << _T(" ");
44
45 if(j + i*colums >= size)
46 {
47 out << _T(" ");
48 }
49 else
50 {
51 wxByte *pos = static_cast<wxByte *>(GetData());
52 pos += (j + i * colums);
53 out << wxString::Format(_T(" %.2x"), *pos);
54 }
55 }
56
57 //seperator
58 out << _T(" ");
59
60 //print ascii
61 for(size_t j = 0; j < colums; j++)
62 {
63 if(j == colums/2)
64 out << _T(" ");
65 if(j + i*colums >= size)
66 {
67 out << _T(" ");
68 }
69 else
70 {
71 wxByte *pos = static_cast<wxByte *>(GetData());
72 pos += ( j + i * colums);
73 out << wxString::Format(_T("%c"), (wxIsprint(*pos) ? *pos : '.'));
74 }
75 }
76
77 out << endl;
78 }
79}
80
diff --git a/wxbufferex.h b/wxbufferex.h
new file mode 100644
index 0000000..7805fe9
--- /dev/null
+++ b/wxbufferex.h
@@ -0,0 +1,42 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef WXMEMORYBUFFEREX_H
20#define WXMEMORYBUFFEREX_H
21
22// Libraries
23#include <wx/wx.h>
24#include <wx/buffer.h>
25#include <wx/stream.h>
26
27//! wxMemoryBufferEx.
28/*! wxMemoryBufferEx.
29 */
30class wxMemoryBufferEx : public wxMemoryBuffer
31{
32 public:
33 wxMemoryBufferEx(size_t s) : wxMemoryBuffer(s)
34 {}
35
36 /*! Hex dump on the stream.
37 * \param strm Stream to write.
38 */
39 void HexDump(wxOutputStream &strm);
40};
41
42#endif
diff --git a/wxstreamex.cpp b/wxstreamex.cpp
new file mode 100644
index 0000000..dfbf7c7
--- /dev/null
+++ b/wxstreamex.cpp
@@ -0,0 +1,108 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19// Header
20#include "wxstreamex.h"
21
22//------------------------------------------------------------------------------
23// Writes a fixed string on the stream
24bool wxDataOutputStreamEx::WriteFixedString(wxString const &str, wxUint8 size)
25{
26 if((str.Length()+1) > size)
27 return false;
28
29 wxCSConv conv_iso(_T("iso-8859-1"));
30 wxCharBuffer buffer = str.mb_str(conv_iso);
31
32 strm->PutC(wxUint8(strlen(buffer)));
33
34 for(size_t i = 0; i < strlen(buffer); i++)
35 strm->PutC(str[i]);
36
37 for(size_t i = 0; i < (size-strlen(buffer)-1); i++)
38 strm->PutC('\0');
39
40 return true;
41}
42
43//------------------------------------------------------------------------------
44// Writes zero terminated string on the stream with zero
45bool wxDataOutputStreamEx::WriteZeroString(wxString const &str)
46{
47 if(str.Length() == 0)
48 return false;
49
50 wxCSConv conv_iso(_T("iso-8859-1"));
51 wxCharBuffer buffer = str.mb_str(conv_iso);
52 strm->Write(buffer, strlen(buffer));
53 strm->PutC('\0');
54
55 return true;
56}
57
58//------------------------------------------------------------------------------
59
60// Reades a fixed string from the stream
61bool wxDataInputStreamEx::ReadFixedString(wxString &str, wxUint8 size)
62{
63 size_t strlen = 0;
64 char buffer[TS_MAX_LENGTH];
65 int i = 0;
66
67 strlen = strm->GetC();
68 for(i = 0; i < size-1; i++)
69 {
70 if(strm->Eof())
71 {
72 buffer[i] = '\0';
73 str = wxString::FromAscii(buffer);
74 return false;
75 }
76
77 buffer[i] = strm->GetC();
78 }
79
80 buffer[i] = '\0';
81 str = wxString::FromAscii(buffer);
82 wxUnusedVar(strlen);
83 return true;
84}
85
86//------------------------------------------------------------------------------
87// Reades a zero terminated string from the stream
88bool wxDataInputStreamEx::ReadZeroString(wxString &str)
89{
90 wxChar c;
91 char buffer[TS_MAX_LENGTH];
92 unsigned i = 0;
93
94 c = strm->GetC();
95 while((c != '\0') && (!strm->Eof()))
96 {
97 buffer[i] = c;
98 i++;
99 c = strm->GetC();
100 }
101 buffer[i] = '\0';
102 str = wxString::FromAscii(buffer);
103 if(strm->Eof())
104 return false;
105
106 return true;
107}
108
diff --git a/wxstreamex.h b/wxstreamex.h
new file mode 100644
index 0000000..6174894
--- /dev/null
+++ b/wxstreamex.h
@@ -0,0 +1,85 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 * Authors: Manuel Mausz (manuel@mausz.at)
16 * Christian Raschko (c.raschko@netcore.at)
17 */
18
19#ifndef WXSTREAMEX_H
20#define WXSTREAMEX_H
21
22// Libraries
23#include <wx/wx.h>
24#include <wx/stream.h>
25#include <wx/datstrm.h>
26
27#define TS_MAX_LENGTH 4069
28
29//! wxDataOutputStreamEx.
30/*! wxDataOutputStreamEx.
31 */
32class wxDataOutputStreamEx : public wxDataOutputStream
33{
34 public:
35 wxDataOutputStreamEx(wxOutputStream &s) : wxDataOutputStream(s)
36 {
37 strm = &s;
38 }
39
40 /*! Writes a fixed string on the stream.
41 * \param str String to write.
42 * \param size Size of fixed string, filled with zeros.
43 * \return Returns false if fails.
44 */
45 bool WriteFixedString(wxString const &str, wxUint8 size = 30);
46
47 /*! Writes zero terminated string on the stream with zero.
48 * \param str String to write.
49 * \return Returns false if fails.
50 */
51 bool WriteZeroString(wxString const &str);
52
53 private:
54 wxOutputStream *strm;
55};
56
57//! wxDataInputStreamEx.
58/*! wxDataInputStreamEx.
59 */
60class wxDataInputStreamEx : public wxDataInputStream
61{
62 public:
63 wxDataInputStreamEx(wxInputStream &s) : wxDataInputStream(s)
64 {
65 strm = &s;
66 }
67
68 /*! Reades a fixed string from the stream.
69 * \param str String to write to.
70 * \param size Size of the fixed string.
71 * \return Returns true if successful.
72 */
73 bool ReadFixedString(wxString &str, wxUint8 size = 30);
74
75 /*! Reades a zero terminated string from the stream.
76 * \param str String to write to.
77 * \return Returns true if successful.
78 */
79 bool ReadZeroString(wxString &str);
80
81 private:
82 wxInputStream *strm;
83};
84
85#endif