diff --git a/pokerth_lib.pro b/pokerth_lib.pro index 75ad37ec..3c4a4af3 100644 --- a/pokerth_lib.pro +++ b/pokerth_lib.pro @@ -81,6 +81,7 @@ HEADERS += \ src/net/serverlobbythread.h \ src/net/serverbanmanager.h \ src/net/servercallback.h \ + src/net/serverircbot.h \ src/net/sessiondata.h \ src/net/sessiondatacallback.h \ src/net/sessionmanager.h \ @@ -183,6 +184,7 @@ SOURCES += \ src/net/common/serverlobbythread.cpp \ src/net/common/serverbanmanager.cpp \ src/net/common/servercallback.cpp \ + src/net/common/serverircbot.cpp \ src/net/common/sessiondata.cpp \ src/net/common/sessiondatacallback.cpp \ src/net/common/sessionmanager.cpp \ diff --git a/src/net/common/ircthread.cpp b/src/net/common/ircthread.cpp index 3d225d38..fa51d7f4 100644 --- a/src/net/common/ircthread.cpp +++ b/src/net/common/ircthread.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ using namespace std; #define IRC_RECV_TIMEOUT_MSEC 50 #define IRC_MAX_RENAME_TRIES 5 #define IRC_MIN_RECONNECT_INTERVAL_SEC 60 +#define IRC_SEND_LIMIT_BYTES 1024 #define IRC_RENAME_ATTACH "|Lobby" #define IRC_MAX_NICK_LEN 16 @@ -39,7 +41,7 @@ using namespace std; struct IrcContext { - IrcContext(IrcThread &t) : ircThread(t), session(NULL), serverPort(0), useIPv6(false), renameTries(0) {} + IrcContext(IrcThread &t) : ircThread(t), session(NULL), serverPort(0), useIPv6(false), renameTries(0), sendingBlocked(false) {} IrcThread &ircThread; irc_session_t *session; string serverAddress; @@ -49,6 +51,9 @@ struct IrcContext string channel; string channelPassword; unsigned renameTries; + bool sendingBlocked; + unsigned sendCounter; + queue sendQueue; }; void irc_auto_rename_nick(irc_session_t *session) @@ -182,6 +187,18 @@ irc_event_channel(irc_session_t *session, const char * /*irc_event*/, const char } } +void +irc_event_unknown(irc_session_t *session, const char * irc_event, const char * /*origin*/, const char ** /*params*/, unsigned /*count*/) +{ + IrcContext *context = (IrcContext *) irc_get_ctx(session); + + if (boost::algorithm::iequals(irc_event, "PONG")) + { + context->sendingBlocked = false; + context->ircThread.FlushQueue(); + } +} + void irc_event_numeric(irc_session_t * session, unsigned irc_event, const char * /*origin*/, const char **params, unsigned count) { @@ -307,7 +324,27 @@ void IrcThread::SendChatMessage(const std::string &msg) { IrcContext &context = GetContext(); - irc_cmd_msg(context.session, context.channel.c_str(), msg.c_str()); + if (!context.sendingBlocked) + { + irc_cmd_msg(context.session, context.channel.c_str(), msg.c_str()); + context.sendCounter += msg.size(); + + if (context.sendCounter >= IRC_SEND_LIMIT_BYTES) + { + context.sendingBlocked = true; + context.sendCounter = 0; + SendPing(); + } + } + else + context.sendQueue.push(msg); +} + +void +IrcThread::SendPing() +{ + IrcContext &context = GetContext(); + irc_send_raw(context.session, "PING %s", context.serverAddress.c_str()); } void @@ -357,7 +394,7 @@ IrcThread::IrcInit() //callbacks.event_umode //callbacks.event_ctcp_rep //callbacks.event_ctcp_action - //callbacks.event_unknown + callbacks.event_unknown = irc_event_unknown; callbacks.event_numeric = irc_event_numeric; //callbacks.event_dcc_chat_req @@ -441,6 +478,19 @@ IrcThread::IrcMain() } } +void +IrcThread::FlushQueue() +{ + IrcContext &context = GetContext(); + + while (!context.sendingBlocked && !context.sendQueue.empty()) + { + string msg(context.sendQueue.front()); + context.sendQueue.pop(); + SendChatMessage(msg); + } +} + void IrcThread::HandleIrcError(int errorCode) { diff --git a/src/net/common/serverircbot.cpp b/src/net/common/serverircbot.cpp new file mode 100644 index 00000000..ea09265c --- /dev/null +++ b/src/net/common/serverircbot.cpp @@ -0,0 +1,305 @@ +/*************************************************************************** + * Copyright (C) 2007 by Lothar May * + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SERVER_RESTART_IRC_BOT_INTERVAL_SEC 86400 // 1 day + +using namespace std; + +ServerIrcBot::ServerIrcBot() +{ +} + +ServerIrcBot::~ServerIrcBot() +{ +} + +void +ServerIrcBot::Init(boost::shared_ptr lobbyThread, boost::shared_ptr ircThread) +{ + m_lobbyThread = lobbyThread; + m_ircThread = ircThread; +} + +void +ServerIrcBot::SignalIrcConnect(const std::string &server) +{ + LOG_MSG("Connected to IRC server " << server << "."); +} + +void +ServerIrcBot::SignalIrcSelfJoined(const std::string &nickName, const std::string &channel) +{ + LOG_MSG("Joined IRC channel " << channel << " as user " << nickName << "."); + m_ircNick = nickName; + m_ircThread->SendPing(); +} + +void +ServerIrcBot::SignalIrcChatMsg(const std::string &nickName, const std::string &msg) +{ + if (m_ircThread) + { + try + { + istringstream msgStream(msg); + string target; + msgStream >> target; + if (boost::algorithm::iequals(target, m_ircNick + ":")) + { + string command; + msgStream >> command; + if (command == "kick") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string playerName(msgStream.str().substr(msgStream.tellg())); + if (!playerName.empty()) + { + if (GetLobbyThread().KickPlayerByName(playerName)) + m_ircThread->SendChatMessage(nickName + ": Successfully kicked player \"" + playerName + "\" from the server."); + else + m_ircThread->SendChatMessage(nickName + ": Player \"" + playerName + "\" was not found on the server."); + } + } + else if (command == "cleaner-reconnect") + { + GetLobbyThread().ReconnectChatBot(); + m_ircThread->SendChatMessage(nickName + ": Cleaner bot reconnect initiated."); + } + else if (command == "showip") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string playerName(msgStream.str().substr(msgStream.tellg())); + if (!playerName.empty()) + { + string ipAddress(GetLobbyThread().GetPlayerIPAddress(playerName)); + if (!ipAddress.empty()) + m_ircThread->SendChatMessage(nickName + ": The IP address of player \"" + playerName + "\" is: \"" + ipAddress + "\""); + else + m_ircThread->SendChatMessage(nickName + ": The IP address of player \"" + playerName + "\" is unknown."); + } + } + else if (command == "bannick") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string playerRegex(msgStream.str().substr(msgStream.tellg())); + if (!playerRegex.empty()) + { + GetLobbyThread().GetBanManager().BanPlayerRegex(playerRegex); + m_ircThread->SendChatMessage(nickName + ": The regex \"" + playerRegex + "\" was added to the player ban list."); + } + } + else if (command == "banip") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string ipAddress; + unsigned durationHours = 12; + msgStream >> ipAddress; + while (msgStream.peek() == ' ') + msgStream.get(); + if (!msgStream.eof()) + msgStream >> durationHours; + if (!ipAddress.empty()) + { + ostringstream durationStr; + durationStr << durationHours; + GetLobbyThread().GetBanManager().BanIPAddress(ipAddress, durationHours); + m_ircThread->SendChatMessage(nickName + ": The IP address \"" + ipAddress + "\" was added to the IP address ban list for " + durationStr.str() + (durationHours == 1 ? " hour." : " hours.")); + } + } + else if (command == "listban") + { + list banList; + GetLobbyThread().GetBanManager().GetBanList(banList); + list::const_iterator i = banList.begin(); + list::const_iterator end = banList.end(); + while (i != end) + { + m_ircThread->SendChatMessage(*i); + ++i; + } + ostringstream banListStream; + banListStream + << nickName << ": Total count of bans: " << banList.size(); + m_ircThread->SendChatMessage(banListStream.str()); + } + else if (command == "removeban") + { + unsigned banId = 0; + msgStream >> banId; + if (GetLobbyThread().GetBanManager().UnBan(banId)) + m_ircThread->SendChatMessage(nickName + ": The ban was successfully removed."); + else + m_ircThread->SendChatMessage(nickName + ": This ban does not exist."); + } + else if (command == "clearban") + { + GetLobbyThread().GetBanManager().ClearBanList(); + m_ircThread->SendChatMessage(nickName + ": All ban lists were cleared."); + } + else if (command == "stat") + { + ServerStats tmpStats = GetLobbyThread().GetStats(); + { + boost::posix_time::time_duration timeDiff(boost::posix_time::second_clock::local_time() - GetLobbyThread().GetStartTime()); + ostringstream statStream; + statStream + << "Server uptime................ " << timeDiff.hours() / 24 << " days " << timeDiff.hours() % 24 << " hours " << timeDiff.minutes() << " minutes " << timeDiff.seconds() << " seconds"; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Players currently on Server.. " << tmpStats.numberOfPlayersOnServer; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Games currently open......... " << tmpStats.numberOfGamesOpen; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Total players ever logged in. " << tmpStats.totalPlayersEverLoggedIn + << " (Max at a time: " << tmpStats.maxPlayersLoggedIn << ")"; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Total games ever open........ " << tmpStats.totalGamesEverCreated + << " (Max at a time: " << tmpStats.maxGamesOpen << ")"; + m_ircThread->SendChatMessage(statStream.str()); + } + } + else if (command == "chat") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string chat(msgStream.str().substr(msgStream.tellg())); + if (!chat.empty() && chat.size() < MAX_CHAT_TEXT_SIZE) + { + GetLobbyThread().SendGlobalChat(chat); + m_ircThread->SendChatMessage(nickName + ": Global chat message sent."); + } + else + m_ircThread->SendChatMessage(nickName + ": Invalid message."); + } + else if (command == "msg") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string message(msgStream.str().substr(msgStream.tellg())); + if (!message.empty() && message.size() < MAX_CHAT_TEXT_SIZE) + { + GetLobbyThread().SendGlobalMsgBox(message); + m_ircThread->SendChatMessage(nickName + ": Global message box sent."); + } + else + m_ircThread->SendChatMessage(nickName + ": Invalid message."); + } + else + m_ircThread->SendChatMessage(nickName + ": Invalid command \"" + command + "\"."); + } + } catch (...) + { + m_ircThread->SendChatMessage(nickName + ": Syntax error. Please check the command."); + } + } +} + +void +ServerIrcBot::SignalIrcError(int errorCode) +{ + LOG_MSG("IRC error " << errorCode << "."); +} + +void +ServerIrcBot::SignalIrcServerError(int errorCode) +{ + LOG_MSG("IRC server error " << errorCode << "."); +} + +void +ServerIrcBot::Run() +{ + if (m_ircThread) + m_ircThread->Run(); +} + +void +ServerIrcBot::Process() +{ + if (m_ircRestartTimer.elapsed().total_seconds() > SERVER_RESTART_IRC_BOT_INTERVAL_SEC) + { + if (m_ircThread) + { + m_ircThread->SignalTermination(); + if (m_ircThread->Join(NET_ADMIN_IRC_TERMINATE_TIMEOUT_MSEC)) + { + boost::shared_ptr tmpIrcThread(new IrcThread(*m_ircThread)); + tmpIrcThread->Run(); + m_ircThread = tmpIrcThread; + } + } + m_ircRestartTimer.reset(); + m_ircRestartTimer.start(); + } +} + +void +ServerIrcBot::SignalTermination() +{ + if (m_ircThread) + m_ircThread->SignalTermination(); +} + +bool +ServerIrcBot::Join(bool wait) +{ + bool terminated = true; + if (m_ircThread) + terminated = m_ircThread->Join(wait ? NET_ADMIN_IRC_TERMINATE_TIMEOUT_MSEC : 0); + return terminated; +} + +ServerLobbyThread & +ServerIrcBot::GetLobbyThread() +{ + assert(m_lobbyThread.get()); + return *m_lobbyThread; +} + diff --git a/src/net/common/servermanager.cpp b/src/net/common/servermanager.cpp index 0aa40ee5..405372d1 100644 --- a/src/net/common/servermanager.cpp +++ b/src/net/common/servermanager.cpp @@ -19,10 +19,9 @@ #include #include -#include #include +#include #include -#include #include #include #include @@ -31,14 +30,13 @@ #include #include -#define SERVER_RESTART_IRC_BOT_INTERVAL_SEC 86400 // 1 day - using namespace std; ServerManager::ServerManager(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager) : m_gui(gui), m_playerConfig(config), m_avatarManager(avatarManager) { m_ioService.reset(new boost::asio::io_service); + m_ircBot.reset(new ServerIrcBot); } ServerManager::~ServerManager() @@ -51,6 +49,8 @@ ServerManager::Init(unsigned serverPort, bool ipv6, ServerNetworkMode mode, cons m_lobbyThread.reset(new ServerLobbyThread(GetGui(), m_playerConfig, m_avatarManager, m_ioService)); GetLobbyThread().Init(pwd, logDir); + m_ircBot->Init(m_lobbyThread, ircThread); + if (mode & NETWORK_MODE_TCP) { boost::shared_ptr tcpAcceptHelper(new ServerAcceptHelper(GetGui(), m_ioService)); @@ -63,7 +63,6 @@ ServerManager::Init(unsigned serverPort, bool ipv6, ServerNetworkMode mode, cons sctpAcceptHelper->Listen(serverPort, ipv6, true, pwd, logDir, m_lobbyThread); m_acceptHelperPool.push_back(sctpAcceptHelper); }*/ - m_ircThread = ircThread; } GuiInterface & @@ -72,251 +71,36 @@ ServerManager::GetGui() return m_gui; } -void -ServerManager::SignalIrcConnect(const std::string &server) +ServerIrcBot & +ServerManager::GetIrcBot() { - LOG_MSG("Connected to IRC server " << server << "."); -} - -void -ServerManager::SignalIrcSelfJoined(const std::string &nickName, const std::string &channel) -{ - LOG_MSG("Joined IRC channel " << channel << " as user " << nickName << "."); - m_ircNick = nickName; -} - -void -ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string &msg) -{ - if (m_ircThread) - { - try - { - istringstream msgStream(msg); - string target; - msgStream >> target; - if (boost::algorithm::iequals(target, m_ircNick + ":")) - { - string command; - msgStream >> command; - if (command == "kick") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string playerName(msgStream.str().substr(msgStream.tellg())); - if (!playerName.empty()) - { - if (GetLobbyThread().KickPlayerByName(playerName)) - m_ircThread->SendChatMessage(nickName + ": Successfully kicked player \"" + playerName + "\" from the server."); - else - m_ircThread->SendChatMessage(nickName + ": Player \"" + playerName + "\" was not found on the server."); - } - } - else if (command == "cleaner-reconnect") - { - GetLobbyThread().ReconnectChatBot(); - m_ircThread->SendChatMessage(nickName + ": Cleaner bot reconnect initiated."); - } - else if (command == "showip") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string playerName(msgStream.str().substr(msgStream.tellg())); - if (!playerName.empty()) - { - string ipAddress(GetLobbyThread().GetPlayerIPAddress(playerName)); - if (!ipAddress.empty()) - m_ircThread->SendChatMessage(nickName + ": The IP address of player \"" + playerName + "\" is: \"" + ipAddress + "\""); - else - m_ircThread->SendChatMessage(nickName + ": The IP address of player \"" + playerName + "\" is unknown."); - } - } - else if (command == "bannick") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string playerRegex(msgStream.str().substr(msgStream.tellg())); - if (!playerRegex.empty()) - { - GetLobbyThread().GetBanManager().BanPlayerRegex(playerRegex); - m_ircThread->SendChatMessage(nickName + ": The regex \"" + playerRegex + "\" was added to the player ban list."); - } - } - else if (command == "banip") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string ipAddress; - unsigned durationHours = 12; - msgStream >> ipAddress; - while (msgStream.peek() == ' ') - msgStream.get(); - if (!msgStream.eof()) - msgStream >> durationHours; - if (!ipAddress.empty()) - { - ostringstream durationStr; - durationStr << durationHours; - GetLobbyThread().GetBanManager().BanIPAddress(ipAddress, durationHours); - m_ircThread->SendChatMessage(nickName + ": The IP address \"" + ipAddress + "\" was added to the IP address ban list for " + durationStr.str() + (durationHours == 1 ? " hour." : " hours.")); - } - } - else if (command == "listban") - { - list banList; - GetLobbyThread().GetBanManager().GetBanList(banList); - list::const_iterator i = banList.begin(); - list::const_iterator end = banList.end(); - while (i != end) - { - m_ircThread->SendChatMessage(*i); - ++i; - } - ostringstream banListStream; - banListStream - << nickName << ": Total count of bans: " << banList.size(); - m_ircThread->SendChatMessage(banListStream.str()); - } - else if (command == "removeban") - { - unsigned banId = 0; - msgStream >> banId; - if (GetLobbyThread().GetBanManager().UnBan(banId)) - m_ircThread->SendChatMessage(nickName + ": The ban was successfully removed."); - else - m_ircThread->SendChatMessage(nickName + ": This ban does not exist."); - } - else if (command == "clearban") - { - GetLobbyThread().GetBanManager().ClearBanList(); - m_ircThread->SendChatMessage(nickName + ": All ban lists were cleared."); - } - else if (command == "stat") - { - ServerStats tmpStats = GetLobbyThread().GetStats(); - { - boost::posix_time::time_duration timeDiff(boost::posix_time::second_clock::local_time() - GetLobbyThread().GetStartTime()); - ostringstream statStream; - statStream - << "Server uptime................ " << timeDiff.hours() / 24 << " days " << timeDiff.hours() % 24 << " hours " << timeDiff.minutes() << " minutes " << timeDiff.seconds() << " seconds"; - m_ircThread->SendChatMessage(statStream.str()); - } - { - ostringstream statStream; - statStream - << "Players currently on Server.. " << tmpStats.numberOfPlayersOnServer; - m_ircThread->SendChatMessage(statStream.str()); - } - { - ostringstream statStream; - statStream - << "Games currently open......... " << tmpStats.numberOfGamesOpen; - m_ircThread->SendChatMessage(statStream.str()); - } - { - ostringstream statStream; - statStream - << "Total players ever logged in. " << tmpStats.totalPlayersEverLoggedIn - << " (Max at a time: " << tmpStats.maxPlayersLoggedIn << ")"; - m_ircThread->SendChatMessage(statStream.str()); - } - { - ostringstream statStream; - statStream - << "Total games ever open........ " << tmpStats.totalGamesEverCreated - << " (Max at a time: " << tmpStats.maxGamesOpen << ")"; - m_ircThread->SendChatMessage(statStream.str()); - } - } - else if (command == "chat") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string chat(msgStream.str().substr(msgStream.tellg())); - if (!chat.empty() && chat.size() < MAX_CHAT_TEXT_SIZE) - { - GetLobbyThread().SendGlobalChat(chat); - m_ircThread->SendChatMessage(nickName + ": Global chat message sent."); - } - else - m_ircThread->SendChatMessage(nickName + ": Invalid message."); - } - else if (command == "msg") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string message(msgStream.str().substr(msgStream.tellg())); - if (!message.empty() && message.size() < MAX_CHAT_TEXT_SIZE) - { - GetLobbyThread().SendGlobalMsgBox(message); - m_ircThread->SendChatMessage(nickName + ": Global message box sent."); - } - else - m_ircThread->SendChatMessage(nickName + ": Invalid message."); - } - else - m_ircThread->SendChatMessage(nickName + ": Invalid command \"" + command + "\"."); - } - } catch (...) - { - m_ircThread->SendChatMessage(nickName + ": Syntax error. Please check the command."); - } - } -} - -void -ServerManager::SignalIrcError(int errorCode) -{ - LOG_MSG("IRC error " << errorCode << "."); -} - -void -ServerManager::SignalIrcServerError(int errorCode) -{ - LOG_MSG("IRC server error " << errorCode << "."); + return *m_ircBot; } void ServerManager::RunAll() { - if (m_ircThread) - m_ircThread->Run(); + m_ircBot->Run(); GetLobbyThread().Run(); } void ServerManager::Process() { - if (m_ircRestartTimer.elapsed().total_seconds() > SERVER_RESTART_IRC_BOT_INTERVAL_SEC) - { - if (m_ircThread) - { - m_ircThread->SignalTermination(); - if (m_ircThread->Join(NET_ADMIN_IRC_TERMINATE_TIMEOUT_MSEC)) - { - boost::shared_ptr tmpIrcThread(new IrcThread(*m_ircThread)); - tmpIrcThread->Run(); - m_ircThread = tmpIrcThread; - } - } - m_ircRestartTimer.reset(); - m_ircRestartTimer.start(); - } + m_ircBot->Process(); } void ServerManager::SignalTerminationAll() { - if (m_ircThread) - m_ircThread->SignalTermination(); + m_ircBot->SignalTermination(); GetLobbyThread().SignalTermination(); } bool ServerManager::JoinAll(bool wait) { - if (m_ircThread) - m_ircThread->Join(wait ? NET_ADMIN_IRC_TERMINATE_TIMEOUT_MSEC : 0); + m_ircBot->Join(wait); return GetLobbyThread().Join(wait ? NET_LOBBY_THREAD_TERMINATE_TIMEOUT_MSEC : 0); } diff --git a/src/net/ircthread.h b/src/net/ircthread.h index 2d76b6bd..638f03e2 100644 --- a/src/net/ircthread.h +++ b/src/net/ircthread.h @@ -41,6 +41,8 @@ public: // Send a chat message to the channel. void SendChatMessage(const std::string &msg); + void SendPing(); + void FlushQueue(); virtual void SignalTermination(); diff --git a/src/net/serverircbot.h b/src/net/serverircbot.h new file mode 100644 index 00000000..bf9478a2 --- /dev/null +++ b/src/net/serverircbot.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2009 by Lothar May * + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/* IRC bot for the server. */ + +#ifndef _SERVERIRCBOT_H_ +#define _SERVERIRCBOT_H_ + +#include +#include +#include +#include + +#include +#include + +class ServerLobbyThread; +class ServerAcceptHelper; +class SenderThread; +class ConfigFile; +class AvatarManager; +class IrcThread; + +class ServerIrcBot : public IrcCallback +{ +public: + ServerIrcBot(); + virtual ~ServerIrcBot(); + + void Init(boost::shared_ptr lobbyThread, boost::shared_ptr ircThread); + + // Main start function. + void Run(); + + // Perform processing. + void Process(); + + void SignalTermination(); + bool Join(bool wait); + + virtual void SignalIrcConnect(const std::string &server); + virtual void SignalIrcSelfJoined(const std::string &nickName, const std::string &channel); + virtual void SignalIrcPlayerJoined(const std::string & /*nickName*/) {} + virtual void SignalIrcPlayerChanged(const std::string & /*oldNick*/, const std::string & /*newNick*/) {} + virtual void SignalIrcPlayerKicked(const std::string & /*nickName*/, const std::string & /*byWhom*/, const std::string & /*reason*/) {} + virtual void SignalIrcPlayerLeft(const std::string & /*nickName*/) {} + virtual void SignalIrcChatMsg(const std::string &nickName, const std::string &msg); + virtual void SignalIrcError(int errorCode); + virtual void SignalIrcServerError(int errorCode); + +protected: + ServerLobbyThread &GetLobbyThread(); + +private: + std::string m_ircNick; + + boost::shared_ptr m_lobbyThread; + boost::shared_ptr m_ircThread; + boost::timers::portable::microsec_timer m_ircRestartTimer; +}; + +#endif diff --git a/src/net/servermanager.h b/src/net/servermanager.h index 5ae029e7..2715d36d 100644 --- a/src/net/servermanager.h +++ b/src/net/servermanager.h @@ -22,7 +22,7 @@ #define _SERVERMANAGER_H_ #include -#include +#include #include #include @@ -30,13 +30,13 @@ #include class ServerLobbyThread; +class IrcThread; class ServerAcceptHelper; class SenderThread; class ConfigFile; class AvatarManager; -class IrcThread; -class ServerManager : public IrcCallback +class ServerManager { public: ServerManager(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager); @@ -55,20 +55,7 @@ public: bool JoinAll(bool wait); GuiInterface &GetGui(); - - virtual void SignalIrcConnect(const std::string &server); - virtual void SignalIrcSelfJoined(const std::string &nickName, const std::string &channel); - virtual void SignalIrcPlayerJoined(const std::string & /*nickName*/) {} - virtual void SignalIrcPlayerChanged(const std::string & /*oldNick*/, const std::string & /*newNick*/) {} - virtual void SignalIrcPlayerKicked(const std::string & /*nickName*/, const std::string & /*byWhom*/, const std::string & /*reason*/) {} - virtual void SignalIrcPlayerLeft(const std::string & /*nickName*/) {} - virtual void SignalIrcChatMsg(const std::string &nickName, const std::string &msg); - virtual void SignalIrcError(int errorCode); - virtual void SignalIrcServerError(int errorCode); - virtual void SignalLobbyPlayerJoined(unsigned, const std::string & /*nickName*/) {} - virtual void SignalLobbyPlayerKicked(const std::string & /*nickName*/, const std::string & /*byWhom*/, const std::string & /*reason*/) {} - virtual void SignalLobbyPlayerLeft(unsigned) {} - + ServerIrcBot &GetIrcBot(); protected: typedef std::list > AcceptHelperList; @@ -80,12 +67,9 @@ private: ConfigFile *m_playerConfig; AvatarManager &m_avatarManager; - std::string m_ircNick; - boost::shared_ptr m_ioService; boost::shared_ptr m_lobbyThread; - boost::shared_ptr m_ircThread; - boost::timers::portable::microsec_timer m_ircRestartTimer; + boost::shared_ptr m_ircBot; AcceptHelperList m_acceptHelperPool; }; diff --git a/src/session.cpp b/src/session.cpp index c125af37..23b7c8e3 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -279,7 +279,7 @@ void Session::startNetworkServer() boost::shared_ptr tmpIrcThread; if (myConfig->readConfigInt("UseAdminIRC")) { - tmpIrcThread = boost::shared_ptr(new IrcThread(myNetServer.get())); + tmpIrcThread = boost::shared_ptr(new IrcThread(&myNetServer->GetIrcBot())); tmpIrcThread->Init( myConfig->readConfigString("AdminIRCServerAddress"),