summaryrefslogtreecommitdiffstats
path: root/tsclient.cpp
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 /tsclient.cpp
downloadtsclient-310a2c101b32a5e71a616027b6a1b788a341bc02.tar.gz
tsclient-310a2c101b32a5e71a616027b6a1b788a341bc02.tar.bz2
tsclient-310a2c101b32a5e71a616027b6a1b788a341bc02.zip
initial GPLv2 releaseHEADmaster
Diffstat (limited to 'tsclient.cpp')
-rw-r--r--tsclient.cpp760
1 files changed, 760 insertions, 0 deletions
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