From 310a2c101b32a5e71a616027b6a1b788a341bc02 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 5 Mar 2013 17:39:48 +0100 Subject: initial GPLv2 release --- tsapp.cpp | 617 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 tsapp.cpp (limited to 'tsapp.cpp') diff --git a/tsapp.cpp b/tsapp.cpp new file mode 100644 index 0000000..3818b4c --- /dev/null +++ b/tsapp.cpp @@ -0,0 +1,617 @@ +/* + * 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 "tsapp.h" +#include "tsheaders.h" + +//Libraries +#include +#include +#include +#include +#include +#if defined(__UNIX__) +# include +#endif + +//------------------------------------------------------------------------------ +// OnInit +bool TSApp::OnInit() +{ + m_pLog = NULL; + m_pLogFile = NULL; + m_pConfig = NULL; + m_pClient = NULL; + m_pQuery = NULL; + m_ConfigFileName = CONFIG_FILE_NAME; + + if (!wxAppConsole::OnInit()) + return false; + + return true; +} + +//------------------------------------------------------------------------------ +// OnExit +int TSApp::OnExit() +{ + //cleanup + wxAppConsole::OnExit(); + + if(m_pLogFile != NULL && m_pLogFile->IsOpened()) + m_pLogFile->Close(); + + if(m_pLogFile != NULL) + delete m_pLogFile; + m_pLogFile = NULL; + + if(m_pQuery != NULL) + delete m_pQuery; + m_pQuery = NULL; + + if(m_pClient != NULL) + delete m_pClient; + m_pClient = NULL; + + if(m_pConfig != NULL) + delete m_pConfig; + m_pConfig = NULL; + + if(m_pLog != NULL) + delete m_pLog; + m_pLog = NULL; + + if(m_pQuery != NULL) + delete m_pQuery; + m_pQuery = NULL; + + return true; +} + +//------------------------------------------------------------------------------ +// Program entry point, replacment for main() +int TSApp::OnRun() +{ + wxStringOutputStream out; + + //UNIX stuff + #if defined(__UNIX__) + if(!m_Foreground && !m_Interactive) + { + int pid = fork(); + if(pid < 0) + { + wxLogError(_T("can't fork")); + return EXIT_FAILURE; + } + else if(pid != 0) + return EXIT_SUCCESS; + + //detach from tty + if (!m_Logtostderr) + { + //close existing file descriptors + for (int fd = getdtablesize() - 1; fd >= 0; fd--) + close(fd); + + //open stdin on /dev/null + open("/dev/null", O_RDWR); + } + } + #endif + + //welcome message + wxPrintf(_T("TeamSpeak Client v0.3 (c)2006-2013 Clan-Server.at\n")); + + m_pLog->SetTimestamp(_T("[%x %X]")); + wxLog::SetActiveTarget(m_pLog); + wxSocketBase::Initialize(); + + m_pClient = new TSClient; + m_pQuery = new TSQueryThread(m_pClient); + + //load config + if(!LoadConfig(m_ConfigFileName)) + { + wxLogError(_T("can't open config file %s"), m_ConfigFileName.c_str()); + return EXIT_FAILURE; + } + + //open logfile + if(m_pLogFileStr.Length() > 0 && !m_Logtostderr && (m_pLogFile == NULL || !m_pLogFile->IsOpened())) + { + m_pLogFile = new wxFFile(m_pLogFileStr.c_str(), _T("a+")); + if(!m_pLogFile->IsOpened()) + { + wxLogError(_T("can't open logfile '%s'."), m_pLogFileStr.c_str()); + return false; + } + if (m_pLog != NULL) + delete m_pLog; + m_pLog = new wxLogStderr((FILE *)m_pLogFile->fp()); + } + + //start query thread + m_pQuery->Start(); + + //check for interactive mode + if(m_Interactive) + Interactive(); + else + { + while(m_pClient->IsReconnectActive()) + { + if(!m_pClient->IsConnected()) + { + m_pClient->Disconnect(); + //some status info + wxLogMessage(_T("TSServer: connecting to %s:%d..."), + m_pClient->GetServer()->GetServerAddress().c_str(), + m_pClient->GetServer()->GetPort()); + + //connect + if(!m_pClient->Connect()) + { + wxLogError(_T("%s, error connecting."), m_pClient->GetLastError().c_str()); + wxSleep(RECONNECT_TIMEOUT); + } + else + wxLogMessage(_T("TSServer: connection established...")); + } + wxSleep(1); + } + } + + wxLogMessage(_T("TSServer: disconnecting...")); + m_pClient->Disconnect(); + m_pQuery->Stop(); + wxSocketBase::Shutdown(); + wxLogMessage(_T("TSServer: shutting down successful.")); + wxLog::SetActiveTarget(NULL); + return EXIT_SUCCESS; +} + +//------------------------------------------------------------------------------ +// Load config +bool TSApp::LoadConfig(wxString const &filename) +{ + wxString str; + if(!wxFileExists(filename)) + return false; + + m_pConfig = new wxFileConfig(_T("TSDaemon"), + wxEmptyString, + filename, + filename, + wxCONFIG_USE_RELATIVE_PATH); + + m_pConfig->Read(_T("LogFile"), &str, _T("")); + if(m_pLogFileStr.Length() <= 0) + m_pLogFileStr = str; + + //TSClient + m_pConfig->Read(_T("TSPlatform"), &str, _T("Windows XP")); + m_pClient->SetPlatform(str); + + m_pConfig->Read(_T("TSVersionNumber"), &str, _T("2.0.32.60")); + m_pClient->SetVersionNumber(str); + + TSPlayer *pTSP = new TSPlayer; + m_pConfig->Read(_T("TSLoginName"), &str, _T("")); + pTSP->SetLoginName(str); + m_pConfig->Read(_T("TSLoginPassword"), &str, _T("")); + pTSP->SetLoginPassword(str); + m_pConfig->Read(_T("TSNickname"), &str, _T("")); + pTSP->SetNickname(str); + //now the TSClient takes care of the pointer. + m_pClient->SetPlayer(pTSP); + + TSServer *pTSS = new TSServer; + m_pConfig->Read(_T("TSServerAddress"), &str, _T("")); + pTSS->SetServerAddress(str); + long l; + m_pConfig->Read(_T("TSPort"), &l, 0); + if(!pTSS->SetPort(l)) + wxLogError(_T("port, %s"), pTSS->GetLastError().c_str()); + + //now the TSClient takes care of the pointer. + m_pClient->SetServer(pTSS); + + m_pConfig->Read(_T("ServerAddress"), &str, _T("")); + m_pQuery->SetServerAddress(str); + + m_pConfig->Read(_T("AllowedAddresses"), &str, _T("")); + m_pQuery->SetAllowedAddresses(str); + + m_pConfig->Read(_T("Port"), &l, 0); + if(!m_pQuery->SetPort(l)) + wxLogError(_T("port, %s"), m_pQuery->GetLastError().c_str()); + + m_pConfig->Read(_T("Password"), &str, _T("")); + if(!m_pQuery->SetPassword(str)) + wxLogError(_T("password, %s"), m_pQuery->GetLastError().c_str()); + + return true; +} + +//------------------------------------------------------------------------------ +// Set parser line description +void TSApp::OnInitCmdLine(wxCmdLineParser &parser) +{ + //declare CmdLineParser + static const wxCmdLineEntryDesc cmdLineDesc[] = + { + { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"), + wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, + { wxCMD_LINE_SWITCH, _T("i"), _T("interactive"), _T("interactive mode"), + wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") , + wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL}, + { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") , + wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL}, + #if defined(__UNIX__) + { wxCMD_LINE_SWITCH, _T("f"), _T("foreground"), _T("run in foreground mode"), + wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL}, + #endif + { wxCMD_LINE_SWITCH, _T("g"), _T("logtostderr"), _T("log everything to stderr"), + wxCMD_LINE_VAL_NONE,wxCMD_LINE_PARAM_OPTIONAL}, + { wxCMD_LINE_OPTION, _T("c"), _T("config"), _T("path to config file"), + wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_OPTION, _T("l"), _T("logfile"), _T("path to log file"), + wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_NONE, NULL, NULL, NULL, (wxCmdLineParamType)0, 0 } //ends list + }; + parser.SetDesc(cmdLineDesc); + + //no long options on windows + #ifdef __WINDOWS__ + parser.DisableLongOptions(); + #endif +} + +//------------------------------------------------------------------------------ +// Process command line options +bool TSApp::OnCmdLineParsed(wxCmdLineParser &parser) +{ + m_Interactive = false; + m_Foreground = false; + m_Logtostderr = false; + + /* Create and hook logtarget in */ + if (m_pLog != NULL) + delete m_pLog; + m_pLog = new wxLogStderr(stdout); + + #if defined __UNIX__ + if(parser.Found(_T("f"))) + m_Foreground = true; + else + m_Foreground = false; + #endif + + if(parser.Found(_T("i"))) + { + m_Interactive = true; + #if defined __UNIX__ + m_Foreground = true; + #endif + } + + if(parser.Found(_T("g"))) + { + if (m_pLog != NULL) + delete m_pLog; + m_pLog = new wxLogStderr(stderr); + m_Logtostderr = true; + } + + if(parser.Found(_T("q"))) + m_pLog->SetLogLevel(wxLOG_FatalError); + + if(parser.Found(_T("v"))) + m_pLog->SetVerbose(true); + + wxString str; + if(parser.Found(_T("c"), &str)) + m_ConfigFileName = str; + + if(parser.Found(_T("l"), &str) && m_pLogFileStr.Length() <= 0) + m_pLogFileStr = str; + + return true; +} + +//------------------------------------------------------------------------------ +// Process help (-h) command line option +bool TSApp::OnCmdLineHelp(wxCmdLineParser &parser) +{ + parser.Usage(); + return false; +} + +//------------------------------------------------------------------------------ +// Process command line options errors +bool TSApp::OnCmdLineError(wxCmdLineParser &parser) +{ + parser.Usage(); + return false; +} + +//------------------------------------------------------------------------------ +// ReadString +wxString TSApp::ReadString(wxString const &str) +{ + wxChar cstr[80]; + wxString s; + wxPrintf(_T("%s: "), str.c_str()); + wxScanf(_T("%s"), cstr); + s = cstr; + return s; +} + +//------------------------------------------------------------------------------ +// Interactive mode +bool TSApp::Interactive() +{ + wxStringOutputStream out; + wxChar cstr[80]; + wxString str; + + wxPrintf(_T("Type \"help\" for all commands.\n")); + do + { + wxPrintf(_T(">")); + wxScanf(_T("%s"), cstr); + str = cstr; + //-------------------------------------------------------- + if(str == _T("cl")) + { + wxPrintf(wxString(_T("-"), 40).c_str()); + wxPrintf(_T("\ndumping channels...\n")); + wxPrintf(_T(" total: %d\n"), m_pClient->GetChannels()->GetCount()); + + for(size_t i = 0; i < m_pClient->GetChannels()->GetCount(); i++) + wxPrintf(_T("%.3d %s\n"), i, m_pClient->GetChannels()->Item(i)->GetName().c_str()); + wxPrintf(_T(" total: %d channels\n"), m_pClient->GetChannels()->GetCount()); + } + //-------------------------------------------------------- + else if(str == _T("pl")) + { + wxPrintf(wxString(_T("-"), 40).c_str()); + wxPrintf(_T("\ndumping players...\n")); + wxPrintf(_T(" total: %d\n"), m_pClient->GetPlayers()->GetCount()); + + for(size_t i = 0; i < m_pClient->GetPlayers()->GetCount(); i++) + wxPrintf(_T("%.3d %s\n"), i, m_pClient->GetPlayers()->Item(i)->GetNickname().c_str()); + wxPrintf(_T(" total: %d players\n"), m_pClient->GetPlayers()->GetCount()); + } + //-------------------------------------------------------- + else if(str == _T("pcl")) + { + wxPrintf(wxString(_T("-"), 40).c_str()); + wxPrintf(_T("\ndumping players with channels...\n")); + wxPrintf(_T(" total: %d\n"), m_pClient->GetPlayers()->GetCount()); + + for(size_t i = 0; i < m_pClient->GetPlayers()->GetCount(); i++) + { + wxUint32 chid = m_pClient->GetPlayers()->Item(i)->GetChannelId(); + wxString nick = m_pClient->GetPlayers()->Item(i)->GetNickname(); + wxString chl = _T("error"); + + for(size_t j = 0; j < m_pClient->GetChannels()->GetCount(); j++) + { + if(m_pClient->GetChannels()->Item(j)->GetId() == chid) + { + chl = m_pClient->GetChannels()->Item(j)->GetName(); + break; + } + } + wxPrintf(_T("%.3d %s \t\t %s\n"), i, nick.c_str(), chl.c_str()); + } + wxPrintf(_T(" total: %d players\n"), m_pClient->GetPlayers()->GetCount()); + } + //-------------------------------------------------------- + else if(str == _T("cc")) + { + TSChannel ch; + wxString str; + + wxPrintf(_T("create channel...\n")); + ch.SetName(ReadString(_T("Name"))); + ch.SetTopic(ReadString(_T("Topic"))); + ch.SetDescription(ReadString(_T("Description"))); + str = ReadString(_T("Password ('.' no pass)")); + if(str != _T(".")) + ch.SetPassword(str); + ch.SetFlags(ReadString(_T("Flags"))); + + if(m_pClient->CreateChannel(&ch)) + wxPrintf(_T("channel created\n")); + else + wxLogError(_T("%s"),m_pClient->GetLastError().c_str()); + } + //-------------------------------------------------------- + else if(str == _T("mc")) + { + TSChannel ch; + TSChannel *pChl; + wxString s,str; + wxPrintf(_T("modify channel...\n")); + + s = ReadString(_T("Name")); + pChl = m_pClient->FindChannel(s); + if(pChl == NULL) + { + wxPrintf(_T("channel not found\n")); + } + else + { + wxPrintf(_T("edit channel\n")); + ch.SetId(pChl->GetId()); + ch.SetName(ReadString(_T("Name"))); + ch.SetTopic(ReadString(_T("Topic"))); + ch.SetDescription(ReadString(_T("Description"))); + str = ReadString(_T("Password ('.' no pass)")); + if(str != _T(".")) + ch.SetPassword(str); + ch.SetFlags(ReadString(_T("Flags"))); + + if(m_pClient->ModifyChannel(&ch)) + wxPrintf(_T("channel modified\n")); + else + wxLogError(_T("%s"),m_pClient->GetLastError().c_str()); + } + } + //-------------------------------------------------------- + else if(str == _T("dc")) + { + wxString s; + TSChannel *pChl; + + wxPrintf(_T("delete channel...\n")); + s = ReadString(_T("Name")); + + pChl = m_pClient->FindChannel(s); + if(pChl == NULL) + { + wxPrintf(_T("channel not found\n")); + } + else + { + if(m_pClient->DeleteChannel(pChl)) + wxPrintf(_T("channel deleted\n")); + else + wxLogError(_T("%s"),m_pClient->GetLastError().c_str()); + } + } + //-------------------------------------------------------- + else if(str == _T("mv")) + { + wxString s; + TSPlayer ply; + TSPlayer *pPly; + TSChannel *pChl; + + wxPrintf(_T("move player...\n")); + s = ReadString(_T("Name")); + + pPly = m_pClient->FindPlayer(s); + if(pPly == NULL) + { + wxPrintf(_T("player not found\n")); + } + else + { + s = ReadString(_T("Channel")); + pChl = m_pClient->FindChannel(s); + if(pChl == NULL) + { + wxPrintf(_T("channel not found\n")); + } + else + { + ply.SetId(pPly->GetId()); + ply.SetChannelId(pChl->GetId()); + + if(m_pClient->MovePlayer(&ply)) + wxPrintf(_T("player moved\n")); + else + wxLogError(_T("%s"),m_pClient->GetLastError().c_str()); + } + } + } + //-------------------------------------------------------- + else if(str == _T("kick")) + { + wxString s; + TSPlayer ply; + TSPlayer *pPly; + + wxPrintf(_T("kick player...\n")); + s = ReadString(_T("Name")); + + pPly = m_pClient->FindPlayer(s); + if(pPly == NULL) + { + wxPrintf(_T("player not found\n")); + } + else + { + s = ReadString(_T("Message")); + + ply.SetId(pPly->GetId()); + + if(m_pClient->KickPlayer(&ply,s)) + wxPrintf(_T("player kicked\n")); + else + wxLogError(_T("%s"),m_pClient->GetLastError().c_str()); + } + + } + //-------------------------------------------------------- + else if(str == _T("exit")) + break; + //-------------------------------------------------------- + else if(str == _T("dump")) + { + m_pClient->Dump(out); + wxPrintf(_T("%s"), out.GetString().c_str()); + } + //-------------------------------------------------------- + else if(str == _T("connect")) + { + m_pClient->Disconnect(); + wxPrintf(_T("connecting...\n")); + if(!m_pClient->Connect()) + wxLogError(_T("%s, terminating."), m_pClient->GetLastError().c_str()); + else + wxPrintf(_T("connected\n")); + } + //-------------------------------------------------------- + else if(str == _T("disconnect")) + { + if(!m_pClient->Disconnect()) + wxLogError(_T("%s, terminating."), m_pClient->GetLastError().c_str()); + else + wxPrintf(_T("disconnected\n")); + } + //-------------------------------------------------------- + else if(str == _T("help")) + { + wxPrintf(_T("pl show player list\n")); + wxPrintf(_T("cl show channel list\n")); + wxPrintf(_T("pcl player with channel list\n")); + wxPrintf(_T("cc create channel\n")); + wxPrintf(_T("dc delete channel\n")); + wxPrintf(_T("mv move player\n")); + wxPrintf(_T("kick kick player\n")); + wxPrintf(_T("mc modify channel\n")); + wxPrintf(_T("connect connect to server\n")); + wxPrintf(_T("disconnect disconnect from server\n")); + wxPrintf(_T("dump full object dump\n")); + wxPrintf(_T("exit exit application\n")); + } + } while(1); + + return true; +} + +//makes the application class known to wxWidgets for dynamic construction +IMPLEMENT_APP_CONSOLE(TSApp) + -- cgit v1.2.3