diff --git a/src/net/common/ircthread.cpp b/src/net/common/ircthread.cpp index 01a790b1..a478a857 100644 --- a/src/net/common/ircthread.cpp +++ b/src/net/common/ircthread.cpp @@ -251,11 +251,30 @@ irc_event_numeric(irc_session_t * session, unsigned irc_event, const char * /*or } } -IrcThread::IrcThread(IrcCallback &callback) +IrcThread::IrcThread(const IrcThread &other) +: m_terminationTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start), + m_lastConnectTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start) +{ + m_callback = other.m_callback; + m_context.reset(new IrcContext(*this)); + + IrcContext &context = GetContext(); + const IrcContext &otherContext = other.GetContext(); + + context.serverAddress = otherContext.serverAddress; + context.serverPort = otherContext.serverPort; + context.useIPv6 = otherContext.useIPv6; + context.nick = otherContext.nick; + context.channel = otherContext.channel; + context.channelPassword = otherContext.channelPassword; +} + +IrcThread::IrcThread(IrcCallback *callback) : m_callback(callback), m_terminationTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start), m_lastConnectTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start) { + assert(callback); m_context.reset(new IrcContext(*this)); } @@ -469,6 +488,7 @@ IrcThread::GetContext() IrcCallback & IrcThread::GetCallback() { - return m_callback; + assert(m_callback); + return *m_callback; } diff --git a/src/net/common/servermanager.cpp b/src/net/common/servermanager.cpp index a3478acd..47146c91 100644 --- a/src/net/common/servermanager.cpp +++ b/src/net/common/servermanager.cpp @@ -32,6 +32,8 @@ #include #include +#define SERVER_RESTART_IRC_BOT_INTERVAL_SEC 86400 // 1 day + using namespace std; ServerManager::ServerManager(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager) @@ -172,6 +174,26 @@ ServerManager::RunAll() for_each(m_acceptThreadPool.begin(), m_acceptThreadPool.end(), boost::mem_fn(&ServerAcceptThread::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(); + } +} + void ServerManager::SignalTerminationAll() { diff --git a/src/net/ircthread.h b/src/net/ircthread.h index b78e8d04..4951e326 100644 --- a/src/net/ircthread.h +++ b/src/net/ircthread.h @@ -31,7 +31,8 @@ struct IrcContext; class IrcThread : public Thread { public: - IrcThread(IrcCallback &callback); + IrcThread(const IrcThread &other); + IrcThread(IrcCallback *callback); virtual ~IrcThread(); // Set the parameters. @@ -58,7 +59,7 @@ protected: private: boost::shared_ptr m_context; - IrcCallback &m_callback; + IrcCallback *m_callback; boost::timers::portable::microsec_timer m_terminationTimer; boost::timers::portable::microsec_timer m_lastConnectTimer; diff --git a/src/net/servermanager.h b/src/net/servermanager.h index e791c9aa..86e16f71 100644 --- a/src/net/servermanager.h +++ b/src/net/servermanager.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -46,6 +47,9 @@ public: // Main start function. void RunAll(); + // Let the server manager perform processing. + void Process(); + void SignalTerminationAll(); bool JoinAll(bool wait); @@ -75,6 +79,7 @@ private: boost::shared_ptr m_lobbyThread; boost::shared_ptr m_ircThread; + boost::timers::portable::microsec_timer m_ircRestartTimer; AcceptThreadList m_acceptThreadPool; }; diff --git a/src/session.cpp b/src/session.cpp index 3b860380..4327c9cd 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -157,7 +157,7 @@ void Session::startInternetClient() if (myConfig->readConfigInt("UseIRCLobbyChat")) { - myClientIrcThread = new IrcThread(*myGui); + myClientIrcThread = new IrcThread(myGui); myClientIrcThread->Init( myConfig->readConfigString("IRCServerAddress"), myConfig->readConfigInt("IRCServerPort"), @@ -281,7 +281,7 @@ void Session::startNetworkServer() boost::shared_ptr tmpIrcThread; if (myConfig->readConfigInt("UseAdminIRC")) { - tmpIrcThread = boost::shared_ptr(new IrcThread(*myNetServer)); + tmpIrcThread = boost::shared_ptr(new IrcThread(myNetServer)); tmpIrcThread->Init( myConfig->readConfigString("AdminIRCServerAddress"), @@ -323,6 +323,7 @@ bool Session::pollNetworkServerTerminated() retVal = true; // already terminated else { + myNetServer->Process(); if (myNetServer->JoinAll(false)) retVal = true; }