/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Manuel Mausz (manuel@mausz.at) * Christian Raschko (c.raschko@netcore.at) */ // Header #include "tsclient.h" //Libraries #include #include #include #include #include #include #include #include #include #include #include IMPLEMENT_CLASS(TSClient, wxObject) IMPLEMENT_CLASS(TSCmd, wxObject) //------------------------------------------------------------------------------ // Default CTor, Initializes the object. TSClient::TSClient() { //create all objects m_pMutex = new wxMutex; m_pPlayer = new TSPlayer; m_ppPlayers = new TSpPlayerArray; m_pChannel = new TSChannel; m_ppChannels = new TSpChannelArray; m_pConnection = NULL; m_pServer = new TSServer; m_pSync = NULL; m_VersionNumber = _T("0.0.0.0"); m_Platform = _T("na"); m_LastError = _T(""); m_SessionId = 0; m_pReconnectAct = true; } //------------------------------------------------------------------------------ // Default DTor. TSClient::~TSClient() { //do the necessary cleanup wxASSERT(m_pPlayer != NULL); delete m_pPlayer; m_pPlayer = NULL; for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { wxASSERT(m_ppPlayers != NULL); delete m_ppPlayers->Item(i); } for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { wxASSERT(m_ppChannels != NULL); delete m_ppChannels->Item(i); } wxASSERT(m_ppPlayers != NULL); delete m_ppPlayers; m_ppPlayers = NULL; wxASSERT(m_pChannel != NULL); delete m_pChannel; m_pChannel = NULL; wxASSERT(m_ppChannels != NULL); delete m_ppChannels; m_ppChannels = NULL; wxASSERT(m_pServer != NULL); delete m_pServer; m_pServer = NULL; if(m_pConnection != NULL) { delete m_pConnection; m_pConnection = NULL; } } //------------------------------------------------------------------------------ // Send a command to a Teasmpeak server. bool TSClient::SendCommand(wxUint32 cmd) { TSCmd sync; sync.id = cmd; sync.error = false; sync.client = this; return SendCommand(&sync); } //------------------------------------------------------------------------------ // Send a command to a Teamspeak server. bool TSClient::SendCommand(TSCmd *cmd) { if(!m_pConnection->IsAlive()) { SetLastError(_T("thread not running")); return false; } m_pMutex->Lock(); m_Lock = true; m_pSync = cmd; m_pMutex->Unlock(); bool error = true; for(int i=0;iLock(); if (!m_Lock) { error = false; break; } m_pMutex->Unlock(); wxMilliSleep(1); } if(error) { SetLastError(_T("thread not responding")); m_pMutex->Unlock(); return false; } cmd = m_pSync; m_pSync = NULL; if(cmd == NULL) { SetLastError(_T("command is NULL")); m_pMutex->Unlock(); return false; } if(cmd->error) { SetLastError(cmd->lasterror); m_pMutex->Unlock(); return false; } if(!cmd->executed) { SetLastError(_T("command not executed")); m_pMutex->Unlock(); return false; } m_pMutex->Unlock(); return true; } //------------------------------------------------------------------------------ // Connects to a Teasmpeak server. bool TSClient::Connect() { if(m_pPlayer == NULL) { SetLastError(_T("no player object")); return false; } if(m_pServer == NULL) { SetLastError(_T("no server object")); return false; } if(m_pConnection == NULL) { //m_pMutex->Lock(); m_pConnection = new TSConnectionThread(this, m_pMutex); //Start thread m_pConnection->Run(); } if(!m_pConnection->IsAlive()) { SetLastError(_T("can't create thread")); return false; } if(!SendCommand(TS_CMD_SEND_LOGIN)) return false; if(!SendCommand(TS_CMD_SEND_DEFAULT)) return false; return true; } //------------------------------------------------------------------------------ // Disconnects from a Teasmpeak server. bool TSClient::Disconnect(bool reconnect) { if(IsConnected()) if(!SendCommand(TS_CMD_SEND_LOGOUT)) return false; wxSleep(1); if(m_pConnection != NULL) { m_pConnection->Delete(); delete m_pConnection; m_pConnection = NULL; } for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { wxASSERT(m_ppPlayers != NULL); delete m_ppPlayers->Item(i); } m_ppPlayers->Empty(); for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { wxASSERT(m_ppChannels != NULL); delete m_ppChannels->Item(i); } m_ppChannels->Empty(); m_pReconnectAct = reconnect; return true; } //------------------------------------------------------------------------------ // Sets the platform string (e.g. Windows XP, Linux). bool TSClient::SetPlatform(wxString const &str) { if(str.Length() == 0) { SetLastError(_T("empty string")); return false; } m_Platform = str; return true; } //------------------------------------------------------------------------------ // Sets the TeamSpeak player. bool TSClient::SetPlayer(TSPlayer *pPlayer) { if(pPlayer == NULL) { SetLastError(_T("invalid pointer")); return false; } wxASSERT(m_pPlayer != NULL); delete m_pPlayer; m_pPlayer = pPlayer; return true; } //------------------------------------------------------------------------------ // Sets the TeamSpeak player channel. bool TSClient::SetChannel(TSChannel *pChannel) { if(pChannel == NULL) { SetLastError(_T("invalid pointer")); return false; } if(m_pChannel != NULL) delete m_pChannel; m_pChannel = pChannel; return true; } //------------------------------------------------------------------------------ // Sets the TeamSpeak server. bool TSClient::SetServer(TSServer *pServer) { if(pServer == NULL) { SetLastError(_T("invalid pointer")); return false; } if(m_pServer != NULL) delete m_pServer; m_pServer = pServer; return true; } //------------------------------------------------------------------------------ // Sets the TeamSpeak connection. bool TSClient::SetConnection(TSConnectionThread *pConnection) { if(pConnection == NULL) { SetLastError(_T("invalid pointer")); return false; } if(m_pConnection != NULL) delete m_pConnection; m_pConnection = pConnection; return true; } //------------------------------------------------------------------------------ // Sets the TeamSpeak client version number bool TSClient::SetVersionNumber(wxString const &str) { if(str.Length() == 0) { SetLastError(_T("empty string")); return false; } m_VersionNumber = str; return true; } //------------------------------------------------------------------------------ // Sets the session id. bool TSClient::SetSessionId(wxUint32 const id) { m_SessionId = id; return true; } //------------------------------------------------------------------------------ // Sets Sync onject, for thread sync. bool TSClient::SetSync(TSCmd *sync) { m_pSync = sync; return true; } //------------------------------------------------------------------------------ // FindPlayer. TSPlayer *TSClient::FindPlayer(wxUint32 id) { for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { if(m_ppPlayers->Item(i)->GetId() == id) return m_ppPlayers->Item(i); } SetLastError(_T("player not found")); return NULL; } //------------------------------------------------------------------------------ // FindPlayer. TSPlayer *TSClient::FindPlayer(wxString const &str) { for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { if(m_ppPlayers->Item(i)->GetNickname() == str) return m_ppPlayers->Item(i); } SetLastError(_T("player not found")); return NULL; } //------------------------------------------------------------------------------ // FindChannel. TSChannel *TSClient::FindChannel(wxUint32 id) { for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { if(m_ppChannels->Item(i)->GetId() == id) return m_ppChannels->Item(i); } SetLastError(_T("channel not found")); return NULL; } //------------------------------------------------------------------------------ // FindChannel. TSChannel *TSClient::FindChannel(wxString const &str) { for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { if(m_ppChannels->Item(i)->GetName() == str) return m_ppChannels->Item(i); } SetLastError(_T("channel not found")); return NULL; } //------------------------------------------------------------------------------ // Finds default channel TSChannel *TSClient::FindDefaultChannel() { for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { if((m_ppChannels->Item(i)->GetFlags() &TS_DEFAULT)) return m_ppChannels->Item(i); } SetLastError(_T("channel not found")); return NULL; } //------------------------------------------------------------------------------ // FindChannelsByParent. bool TSClient::FindChannelsByParent(wxUint32 id, TSpChannelArray *channels) { for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { if(m_ppChannels->Item(i)->GetParent() == id) channels->Add(m_ppChannels->Item(i)); } if(channels->GetCount() == 0) { SetLastError(_T("no channels found")); return false; } return true; } //------------------------------------------------------------------------------ // FindChannelsByName. bool TSClient::FindChannelsByName(wxString const &str, TSpChannelArray *channels) { wxRegEx regex; regex.Compile(str); if(!regex.IsValid()) { SetLastError(_T("regular expressions pattern error")); return false; } for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { if(regex.Matches(m_ppChannels->Item(i)->GetName())) channels->Add(m_ppChannels->Item(i)); } if(channels->GetCount() == 0) { SetLastError(_T("no channels found")); return false; } return true; } //------------------------------------------------------------------------------ // FindPlayersByName. bool TSClient::FindPlayersByName(wxString const &str, TSpPlayerArray *players) { wxRegEx regex; regex.Compile(str); if(!regex.IsValid()) { SetLastError(_T("regular expressions pattern error")); return false; } for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { if(regex.Matches(m_ppPlayers->Item(i)->GetNickname())) players->Add(m_ppPlayers->Item(i)); } if(players->GetCount() == 0) { SetLastError(_T("no player found")); return false; } return true; } //------------------------------------------------------------------------------ // Finds all players in channel. bool TSClient::FindPlayersByChannel(TSChannel *channel, TSpPlayerArray *players) { if(channel == NULL) { SetLastError(_T("invalid pointer")); return false; } for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { if(m_ppPlayers->Item(i)->GetChannelId() == channel->GetId()) players->Add(m_ppPlayers->Item(i)); } if(players->GetCount() == 0) { SetLastError(_T("no player found")); return false; } return true; } //------------------------------------------------------------------------------ // Creates a channel. bool TSClient::CreateChannel(TSChannel *channel) { if(channel == NULL) { SetLastError(_T("invalid pointer")); return false; } TSCmd sync; sync.id = TS_CMD_SEND_ADD_CHANNEL; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; return true; } //------------------------------------------------------------------------------ // Deletes a channel. bool TSClient::DeleteChannel(TSChannel *channel) { if(channel == NULL) { SetLastError(_T("invalid pointer")); return false; } TSCmd sync; sync.id = TS_CMD_SEND_DEL_CHANNEL; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; return true; } //------------------------------------------------------------------------------ // Moves a Player. bool TSClient::MovePlayer(TSPlayer *player) { if(player == NULL) { SetLastError(_T("invalid pointer")); return false; } TSCmd sync; sync.id = TS_CMD_SEND_MOVE_PLAYER; sync.client = this; sync.param1.pPlayer = player; if(!SendCommand(&sync)) return false; return true; } //------------------------------------------------------------------------------ // Modify Channel. bool TSClient::ModifyChannel(TSChannel *channel) { if(channel == NULL) { SetLastError(_T("invalid pointer")); return false; } if(channel->GetPassword().Length()!= 0) { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_PASSWORD; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_FLAGSCODEC; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_NAME; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_TOPIC; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_DESCRIPTION; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_MAXPLAYERS; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } #if 0 { TSCmd sync; sync.id = TS_CMD_SEND_SET_CHANNEL_ORDER; sync.client = this; sync.param1.pChannel = channel; if(!SendCommand(&sync)) return false; } #endif return true; } //------------------------------------------------------------------------------ // Check if connected. bool TSClient::IsConnected() { if(m_pConnection != NULL) return m_pConnection->m_Connected; return false; } //------------------------------------------------------------------------------ // Kick a Player. bool TSClient::KickPlayer(TSPlayer *player, wxString msg) { if(player == NULL) { SetLastError(_T("invalid pointer")); return false; } TSCmd sync; sync.id = TS_CMD_SEND_KICK_PLAYER; sync.client = this; sync.param1.pPlayer = player; sync.param2.pString = &msg; if(!SendCommand(&sync)) return false; return true; } //------------------------------------------------------------------------------ // Dumps object. void TSClient::Dump(wxOutputStream &ostrm) const { wxTextOutputStream out(ostrm); out << wxString(_T("-"), 60) << endl; out << _T("Object: TSClient (") << wxString::Format(_T("0x%X"), this) << _T(")") << endl; out << wxString(_T("-"), 60) << endl; out << _T("-TSPlayer *m_pPlayer:") << endl; m_pPlayer->Dump(ostrm); out << endl; //TSpPlayerArray out << wxString(_T("-"), 60) << endl; out << _T("-TSpPlayerArray *m_ppPlayers:") << endl; out << _T(" total objects: ") << wxUint32(m_ppPlayers->GetCount()) << endl; for(size_t i = 0; i < m_ppPlayers->GetCount(); i++) { out << _T("\n*Item: ") << wxUint32(i) << endl; m_ppPlayers->Item(i)->Dump(ostrm); } out << endl; out << wxString(_T("-"), 60) << endl; out << _T("-TSChannel *m_pChannel:") << endl; m_pChannel->Dump(ostrm); out << endl; //TSpChannelArray out << wxString(_T("-"), 60) << endl; out << _T("-TSpChannelArray *m_ppChannels:") << endl; out << _T(" total objects: ") << wxUint32(m_ppChannels->GetCount()) << endl; for(size_t i = 0; i < m_ppChannels->GetCount(); i++) { out << _T("\n*Item: ") << wxUint32(i) << endl; m_ppChannels->Item(i)->Dump(ostrm); } out << endl; //TSServer out << wxString(_T("-"), 60) << endl; out << _T("-TSServer *m_pServer:") << endl; m_pServer->Dump(ostrm); out << endl; //remaining members out << wxString(_T("-"), 60) << endl; out << _T("-wxString m_VersionNumber: ") << m_VersionNumber << endl; out << _T("-wxString m_Platform: ") << m_Platform << endl; out << _T("-wxUint32 m_SessionId: ") << wxString::Format(_T("0x%X"), m_SessionId) << endl; out << _T("-wxString m_LastError: ") << m_LastError << endl; }