Added support for password protected irc channels. Added server IRC mode for admin use, to allow requesting statistics and kicking players.

This commit is contained in:
lotodore
2007-11-16 00:58:23 +00:00
parent 991c4367e2
commit cdd21250de
14 changed files with 277 additions and 50 deletions
+8 -1
View File
@@ -53,7 +53,7 @@ ConfigFile::ConfigFile(int argc, char **argv) : noWriteAccess(0)
if(strcmp(argv[i], "--nowriteaccess") == 0) { noWriteAccess = 1; } if(strcmp(argv[i], "--nowriteaccess") == 0) { noWriteAccess = 1; }
} }
// !!!! Revisionsnummer der Configdefaults !!!!! // !!!! Revisionsnummer der Configdefaults !!!!!
configRev = 51; configRev = 52;
//standard defaults //standard defaults
logOnOffDefault = "1"; logOnOffDefault = "1";
@@ -216,6 +216,13 @@ ConfigFile::ConfigFile(int argc, char **argv) : noWriteAccess(0)
configList.push_back(ConfigInfo("IRCChannel", CONFIG_TYPE_STRING, "#pokerth-lobby")); configList.push_back(ConfigInfo("IRCChannel", CONFIG_TYPE_STRING, "#pokerth-lobby"));
configList.push_back(ConfigInfo("IRCChannelPassword", CONFIG_TYPE_STRING, "")); configList.push_back(ConfigInfo("IRCChannelPassword", CONFIG_TYPE_STRING, ""));
configList.push_back(ConfigInfo("IRCServerUseIpv6", CONFIG_TYPE_INT, "0")); configList.push_back(ConfigInfo("IRCServerUseIpv6", CONFIG_TYPE_INT, "0"));
configList.push_back(ConfigInfo("UseAdminIRC", CONFIG_TYPE_INT, "0"));
configList.push_back(ConfigInfo("AdminIRCServerAddress", CONFIG_TYPE_STRING, "chat.freenode.net"));
configList.push_back(ConfigInfo("AdminIRCServerPort", CONFIG_TYPE_INT, "6667"));
configList.push_back(ConfigInfo("AdminIRCChannel", CONFIG_TYPE_STRING, "#test"));
configList.push_back(ConfigInfo("AdminIRCChannelPassword", CONFIG_TYPE_STRING, ""));
configList.push_back(ConfigInfo("AdminIRCServerUseIpv6", CONFIG_TYPE_INT, "0"));
configList.push_back(ConfigInfo("AdminIRCServerNick", CONFIG_TYPE_INT, "PokerTH"));
configList.push_back(ConfigInfo("MyName", CONFIG_TYPE_STRING, "Human Player")); configList.push_back(ConfigInfo("MyName", CONFIG_TYPE_STRING, "Human Player"));
configList.push_back(ConfigInfo("MyAvatar", CONFIG_TYPE_STRING, "")); configList.push_back(ConfigInfo("MyAvatar", CONFIG_TYPE_STRING, ""));
configList.push_back(ConfigInfo("Opponent1Name", CONFIG_TYPE_STRING, "Player 1")); configList.push_back(ConfigInfo("Opponent1Name", CONFIG_TYPE_STRING, "Player 1"));
+4 -4
View File
@@ -70,12 +70,12 @@ enum Button {
struct ServerStats struct ServerStats
{ {
ServerStats() ServerStats()
: numberOfPlayersOnServer(0), totalPlayersEverLoggedIn(0), totalGamesEverStarted(0), : numberOfPlayersOnServer(0), totalPlayersEverLoggedIn(0), totalGamesEverCreated(0),
maxGamesRunning(0), maxPlayersLoggedIn(0) {} maxGamesOpen(0), maxPlayersLoggedIn(0) {}
unsigned numberOfPlayersOnServer; unsigned numberOfPlayersOnServer;
unsigned totalPlayersEverLoggedIn; unsigned totalPlayersEverLoggedIn;
unsigned totalGamesEverStarted; unsigned totalGamesEverCreated;
unsigned maxGamesRunning; unsigned maxGamesOpen;
unsigned maxPlayersLoggedIn; unsigned maxPlayersLoggedIn;
}; };
+2 -2
View File
@@ -956,8 +956,8 @@ ClientThread::UpdateStatData(const ServerStats &stats)
if (stats.totalPlayersEverLoggedIn) if (stats.totalPlayersEverLoggedIn)
m_curStats.totalPlayersEverLoggedIn = stats.totalPlayersEverLoggedIn; m_curStats.totalPlayersEverLoggedIn = stats.totalPlayersEverLoggedIn;
if (stats.totalGamesEverStarted) if (stats.totalGamesEverCreated)
m_curStats.totalGamesEverStarted = stats.totalGamesEverStarted; m_curStats.totalGamesEverCreated = stats.totalGamesEverCreated;
GetCallback().SignalNetClientStatsUpdate(m_curStats); GetCallback().SignalNetClientStatsUpdate(m_curStats);
} }
+4 -2
View File
@@ -43,6 +43,7 @@ struct IrcContext
bool useIPv6; bool useIPv6;
string nick; string nick;
string channel; string channel;
string channelPassword;
unsigned renameTries; unsigned renameTries;
}; };
@@ -106,7 +107,7 @@ irc_event_connect(irc_session_t *session, const char * /*irc_event*/, const char
IrcContext *context = (IrcContext *) irc_get_ctx(session); IrcContext *context = (IrcContext *) irc_get_ctx(session);
context->ircThread.GetCallback().SignalIrcConnect(origin); context->ircThread.GetCallback().SignalIrcConnect(origin);
irc_cmd_join(session, context->channel.c_str(), 0); irc_cmd_join(session, context->channel.c_str(), context->channelPassword.c_str());
} }
void void
@@ -259,7 +260,7 @@ IrcThread::~IrcThread()
} }
void void
IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &nick, const std::string &channel) IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &nick, const std::string &channel, const std::string &channelPassword)
{ {
if (IsRunning() || serverAddress.empty() || nick.empty() || channel.empty()) if (IsRunning() || serverAddress.empty() || nick.empty() || channel.empty())
return; // TODO: throw exception return; // TODO: throw exception
@@ -271,6 +272,7 @@ IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6
context.useIPv6 = ipv6; context.useIPv6 = ipv6;
context.nick = nick; context.nick = nick;
context.channel = channel; context.channel = channel;
context.channelPassword = channelPassword;
// Initialize libirc stuff. // Initialize libirc stuff.
irc_callbacks_t callbacks; irc_callbacks_t callbacks;
+4 -4
View File
@@ -4092,7 +4092,7 @@ NetPacketStatisticsChanged::SetData(const NetPacketStatisticsChanged::Data &inDa
++numValues; ++numValues;
if (inData.stats.totalPlayersEverLoggedIn) if (inData.stats.totalPlayersEverLoggedIn)
++numValues; ++numValues;
if (inData.stats.totalGamesEverStarted) if (inData.stats.totalGamesEverCreated)
++numValues; ++numValues;
// Resize the packet so that the data fits in. // Resize the packet so that the data fits in.
@@ -4118,10 +4118,10 @@ NetPacketStatisticsChanged::SetData(const NetPacketStatisticsChanged::Data &inDa
curStatisticsData->statisticsValue = htonl(inData.stats.totalPlayersEverLoggedIn); curStatisticsData->statisticsValue = htonl(inData.stats.totalPlayersEverLoggedIn);
++curStatisticsData; ++curStatisticsData;
} }
if (inData.stats.totalGamesEverStarted) if (inData.stats.totalGamesEverCreated)
{ {
curStatisticsData->statisticsType = htonl(NET_STAT_TOTAL_GAMES_EVER_ON_SERVER); curStatisticsData->statisticsType = htonl(NET_STAT_TOTAL_GAMES_EVER_ON_SERVER);
curStatisticsData->statisticsValue = htonl(inData.stats.totalGamesEverStarted); curStatisticsData->statisticsValue = htonl(inData.stats.totalGamesEverCreated);
} }
// Check the packet - just in case. // Check the packet - just in case.
@@ -4148,7 +4148,7 @@ NetPacketStatisticsChanged::GetData(NetPacketStatisticsChanged::Data &outData) c
outData.stats.totalPlayersEverLoggedIn = ntohl(curStatisticsData->statisticsValue); outData.stats.totalPlayersEverLoggedIn = ntohl(curStatisticsData->statisticsValue);
break; break;
case NET_STAT_TOTAL_GAMES_EVER_ON_SERVER: case NET_STAT_TOTAL_GAMES_EVER_ON_SERVER:
outData.stats.totalGamesEverStarted = ntohl(curStatisticsData->statisticsValue); outData.stats.totalGamesEverCreated = ntohl(curStatisticsData->statisticsValue);
break; break;
} }
} }
+75 -2
View File
@@ -19,6 +19,7 @@
#include <net/serveracceptthread.h> #include <net/serveracceptthread.h>
#include <net/servercontext.h> #include <net/servercontext.h>
#include <net/ircthread.h>
#include <net/connectdata.h> #include <net/connectdata.h>
#include <net/serverlobbythread.h> #include <net/serverlobbythread.h>
#include <net/socket_helper.h> #include <net/socket_helper.h>
@@ -27,6 +28,8 @@
#include <net/socket_startup.h> #include <net/socket_startup.h>
#include <core/loghelper.h> #include <core/loghelper.h>
#include <boost/algorithm/string/predicate.hpp>
#define ACCEPT_TIMEOUT_MSEC 50 #define ACCEPT_TIMEOUT_MSEC 50
#define NET_SERVER_LISTEN_BACKLOG 5 #define NET_SERVER_LISTEN_BACKLOG 5
@@ -44,7 +47,7 @@ ServerAcceptThread::~ServerAcceptThread()
} }
void void
ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const string &pwd, const string &logDir) ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const string &pwd, const string &logDir, boost::shared_ptr<IrcThread> ircThread)
{ {
if (IsRunning()) if (IsRunning())
{ {
@@ -61,6 +64,7 @@ ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const string
context.SetServerPort(serverPort); context.SetServerPort(serverPort);
GetLobbyThread().Init(pwd, logDir); GetLobbyThread().Init(pwd, logDir);
m_ircThread = ircThread;
} }
ServerCallback & ServerCallback &
@@ -75,12 +79,75 @@ ServerAcceptThread::GetGui()
return m_gui; return m_gui;
} }
void
ServerAcceptThread::SignalIrcConnect(const std::string &server)
{
LOG_MSG("Connected to IRC server " << server << ".");
}
void
ServerAcceptThread::SignalIrcSelfJoined(const std::string &nickName, const std::string &channel)
{
LOG_MSG("Joined IRC channel " << channel << " as user " << nickName << ".");
m_ircNick = nickName;
}
void
ServerAcceptThread::SignalIrcChatMsg(const std::string &nickName, const std::string &msg)
{
if (m_ircThread)
{
istringstream msgStream(msg);
string target;
msgStream >> target;
if (boost::algorithm::iequals(target, m_ircNick + ":"))
{
string command;
msgStream >> command;
if (command == "kick")
{
string playerName;
msgStream >> playerName;
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 == "stat")
{
ServerStats tmpStats = GetLobbyThread().GetStats();
ostringstream statStream;
statStream
<< "Players on Server: " << tmpStats.numberOfPlayersOnServer;
m_ircThread->SendChatMessage(statStream.str());
}
else
m_ircThread->SendChatMessage(nickName + ": Invalid command \"" + command + "\".");
}
}
}
void
ServerAcceptThread::SignalIrcError(int errorCode)
{
}
void
ServerAcceptThread::SignalIrcServerError(int errorCode)
{
}
void void
ServerAcceptThread::Main() ServerAcceptThread::Main()
{ {
try try
{ {
Listen(); Listen();
if (m_ircThread)
m_ircThread->Run();
GetLobbyThread().Run(); GetLobbyThread().Run();
while (!ShouldTerminate() && !GetLobbyThread().Join(0)) while (!ShouldTerminate() && !GetLobbyThread().Join(0))
@@ -94,7 +161,13 @@ ServerAcceptThread::Main()
LOG_ERROR(e.what()); LOG_ERROR(e.what());
} }
GetLobbyThread().SignalTermination(); GetLobbyThread().SignalTermination();
GetLobbyThread().Join(LOBBY_THREAD_TERMINATE_TIMEOUT); GetLobbyThread().Join(LOBBY_THREAD_TERMINATE_TIMEOUT_MSEC);
if (m_ircThread)
{
m_ircThread->SignalTermination();
m_ircThread->Join(ADMIN_IRC_TERMINATE_TIMEOUT_MSEC);
}
} }
void void
+27
View File
@@ -87,6 +87,13 @@ ServerGameThread::AddSession(SessionWrapper session)
m_sessionQueue.push_back(session); m_sessionQueue.push_back(session);
} }
void
ServerGameThread::KickPlayer(unsigned playerId)
{
boost::mutex::scoped_lock lock(m_kickPlayerListMutex);
m_kickPlayerList.push_back(playerId);
}
GameState GameState
ServerGameThread::GetCurRound() const ServerGameThread::GetCurRound() const
{ {
@@ -141,6 +148,7 @@ ServerGameThread::Main()
} }
// Process current state. // Process current state.
GetState().Process(*this); GetState().Process(*this);
KickPlayerLoop();
} while (!ShouldTerminate() && GetSessionManager().HasSessions()); } while (!ShouldTerminate() && GetSessionManager().HasSessions());
} catch (const PokerTHException &e) } catch (const PokerTHException &e)
{ {
@@ -155,6 +163,25 @@ ServerGameThread::Main()
GetLobbyThread().RemoveGame(GetId()); GetLobbyThread().RemoveGame(GetId());
} }
void
ServerGameThread::KickPlayerLoop()
{
boost::mutex::scoped_lock lock(m_kickPlayerListMutex);
PlayerIdList::iterator i = m_kickPlayerList.begin();
PlayerIdList::iterator end = m_kickPlayerList.end();
while (i != end)
{
SessionWrapper tmpSession = GetSessionManager().GetSessionByUniquePlayerId(*i);
// Only kick if the player was found.
if (tmpSession.sessionData.get())
SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
++i;
}
m_kickPlayerList.clear();
}
void void
ServerGameThread::InternalStartGame() ServerGameThread::InternalStartGame()
{ {
+83 -14
View File
@@ -43,8 +43,8 @@
#define SERVER_STATISTICS_FILE_NAME "server_statistics.log" #define SERVER_STATISTICS_FILE_NAME "server_statistics.log"
#define SERVER_STATISTICS_STR_TOTAL_PLAYERS "TotalNumPlayersLoggedIn" #define SERVER_STATISTICS_STR_TOTAL_PLAYERS "TotalNumPlayersLoggedIn"
#define SERVER_STATISTICS_STR_TOTAL_GAMES "TotalNumGamesStarted" #define SERVER_STATISTICS_STR_TOTAL_GAMES "TotalNumGamesCreated"
#define SERVER_STATISTICS_STR_MAX_GAMES "MaxGamesRunning" #define SERVER_STATISTICS_STR_MAX_GAMES "MaxGamesOpen"
#define SERVER_STATISTICS_STR_MAX_PLAYERS "MaxPlayersLoggedIn" #define SERVER_STATISTICS_STR_MAX_PLAYERS "MaxPlayersLoggedIn"
using namespace std; using namespace std;
@@ -201,14 +201,6 @@ ServerLobbyThread::NotifyStartingGame(unsigned gameId)
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED); boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED);
m_sessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Established); m_sessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Established);
m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Game); m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Game);
{
boost::mutex::scoped_lock lock(m_statMutex);
++m_statData.totalGamesEverStarted;
if (m_statData.totalGamesEverStarted > m_statData.maxGamesRunning)
m_statData.maxGamesRunning = m_statData.totalGamesEverStarted;
m_statDataChanged = true;
}
} }
void void
@@ -233,6 +225,24 @@ ServerLobbyThread::HandleGameRetrieveAvatar(SessionWrapper session, const NetPac
HandleNetPacketRetrieveAvatar(session, tmpPacket); HandleNetPacketRetrieveAvatar(session, tmpPacket);
} }
bool
ServerLobbyThread::KickPlayerByName(const std::string &playerName)
{
bool retVal = false;
SessionWrapper session = m_sessionManager.GetSessionByPlayerName(playerName);
if (!session.sessionData.get())
session = m_gameSessionManager.GetSessionByPlayerName(playerName);
if (session.sessionData.get() && session.playerData.get())
{
boost::mutex::scoped_lock lock(m_kickPlayerListMutex);
m_kickPlayerList.push_back(session.playerData->GetUniqueId());
retVal = true;
}
return retVal;
}
void void
ServerLobbyThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player) ServerLobbyThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
{ {
@@ -260,6 +270,13 @@ ServerLobbyThread::GetAvatarManager()
return m_avatarManager; return m_avatarManager;
} }
ServerStats
ServerLobbyThread::GetStats() const
{
boost::mutex::scoped_lock lock(m_statMutex);
return m_statData;
}
u_int32_t u_int32_t
ServerLobbyThread::GetNextUniquePlayerId() ServerLobbyThread::GetNextUniquePlayerId()
{ {
@@ -293,6 +310,8 @@ ServerLobbyThread::Main()
CloseSessionLoop(); CloseSessionLoop();
// Remove games. // Remove games.
RemoveGameLoop(); RemoveGameLoop();
// Kick players.
KickPlayerLoop();
// Cleanup cache. // Cleanup cache.
CleanupAvatarCache(); CleanupAvatarCache();
// Save statistics if needed. // Save statistics if needed.
@@ -773,6 +792,22 @@ ServerLobbyThread::RemoveGameLoop()
m_removeGameList.clear(); m_removeGameList.clear();
} }
void
ServerLobbyThread::KickPlayerLoop()
{
boost::mutex::scoped_lock lock(m_kickPlayerListMutex);
PlayerIdList::iterator i = m_kickPlayerList.begin();
PlayerIdList::iterator end = m_kickPlayerList.end();
while (i != end)
{
InternalKickPlayer(*i);
++i;
}
m_kickPlayerList.clear();
}
void void
ServerLobbyThread::CleanupAvatarCache() ServerLobbyThread::CleanupAvatarCache()
{ {
@@ -794,6 +829,15 @@ ServerLobbyThread::InternalAddGame(boost::shared_ptr<ServerGameThread> game)
// Notify all players. // Notify all players.
m_sessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established); m_sessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established);
m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game); m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game);
{
boost::mutex::scoped_lock lock(m_statMutex);
++m_statData.totalGamesEverCreated;
unsigned numGames = static_cast<unsigned>(m_gameMap.size());
if (numGames > m_statData.maxGamesOpen)
m_statData.maxGamesOpen = numGames;
m_statDataChanged = true;
}
} }
void void
@@ -809,6 +853,31 @@ ServerLobbyThread::InternalRemoveGame(boost::shared_ptr<ServerGameThread> game)
m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Game); m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Game);
} }
void
ServerLobbyThread::InternalKickPlayer(unsigned playerId)
{
SessionWrapper session = m_sessionManager.GetSessionByUniquePlayerId(playerId);
if (session.sessionData.get())
SessionError(session, ERR_NET_PLAYER_KICKED);
else
{
// Scan games for the player.
GameMap::iterator i = m_gameMap.begin();
GameMap::iterator end = m_gameMap.end();
while (i != end)
{
boost::shared_ptr<ServerGameThread> tmpGame = i->second;
if (tmpGame->GetPlayerDataByUniqueId(playerId).get())
{
tmpGame->KickPlayer(playerId);
break;
}
++i;
}
}
}
void void
ServerLobbyThread::TerminateGames() ServerLobbyThread::TerminateGames()
{ {
@@ -982,11 +1051,11 @@ ServerLobbyThread::ReadStatisticsFile()
if (statisticsType == SERVER_STATISTICS_STR_TOTAL_PLAYERS) if (statisticsType == SERVER_STATISTICS_STR_TOTAL_PLAYERS)
m_statData.totalPlayersEverLoggedIn = statisticsValue; m_statData.totalPlayersEverLoggedIn = statisticsValue;
else if (statisticsType == SERVER_STATISTICS_STR_TOTAL_GAMES) else if (statisticsType == SERVER_STATISTICS_STR_TOTAL_GAMES)
m_statData.totalGamesEverStarted = statisticsValue; m_statData.totalGamesEverCreated = statisticsValue;
else if (statisticsType == SERVER_STATISTICS_STR_MAX_PLAYERS) else if (statisticsType == SERVER_STATISTICS_STR_MAX_PLAYERS)
m_statData.maxPlayersLoggedIn = statisticsValue; m_statData.maxPlayersLoggedIn = statisticsValue;
else if (statisticsType == SERVER_STATISTICS_STR_MAX_GAMES) else if (statisticsType == SERVER_STATISTICS_STR_MAX_GAMES)
m_statData.maxGamesRunning = statisticsValue; m_statData.maxGamesOpen = statisticsValue;
} while (!i.fail() && !i.eof()); } while (!i.fail() && !i.eof());
m_statDataChanged = false; m_statDataChanged = false;
} }
@@ -1005,9 +1074,9 @@ ServerLobbyThread::SaveStatisticsFile()
if (!o.fail()) if (!o.fail())
{ {
o << SERVER_STATISTICS_STR_TOTAL_PLAYERS " " << m_statData.totalPlayersEverLoggedIn << endl; o << SERVER_STATISTICS_STR_TOTAL_PLAYERS " " << m_statData.totalPlayersEverLoggedIn << endl;
o << SERVER_STATISTICS_STR_TOTAL_GAMES " " << m_statData.totalGamesEverStarted << endl; o << SERVER_STATISTICS_STR_TOTAL_GAMES " " << m_statData.totalGamesEverCreated << endl;
o << SERVER_STATISTICS_STR_MAX_PLAYERS " " << m_statData.maxPlayersLoggedIn << endl; o << SERVER_STATISTICS_STR_MAX_PLAYERS " " << m_statData.maxPlayersLoggedIn << endl;
o << SERVER_STATISTICS_STR_MAX_GAMES " " << m_statData.maxGamesRunning << endl; o << SERVER_STATISTICS_STR_MAX_GAMES " " << m_statData.maxGamesOpen << endl;
m_statDataChanged = false; m_statDataChanged = false;
} }
} }
+1 -1
View File
@@ -35,7 +35,7 @@ public:
virtual ~IrcThread(); virtual ~IrcThread();
// Set the parameters. // Set the parameters.
void Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &nick, const std::string &channel); void Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &nick, const std::string &channel, const std::string &channelPassword);
// Send a chat message to the channel. // Send a chat message to the channel.
void SendChatMessage(const std::string &msg); void SendChatMessage(const std::string &msg);
+17 -2
View File
@@ -23,6 +23,7 @@
#include <game_defs.h> #include <game_defs.h>
#include <core/thread.h> #include <core/thread.h>
#include <gui/guiinterface.h> #include <gui/guiinterface.h>
#include <string> #include <string>
@@ -32,20 +33,31 @@ class ServerSenderCallback;
class SenderThread; class SenderThread;
class ConfigFile; class ConfigFile;
class AvatarManager; class AvatarManager;
class IrcThread;
struct GameData; struct GameData;
class ServerAcceptThread : public Thread class ServerAcceptThread : public Thread, public IrcCallback
{ {
public: public:
ServerAcceptThread(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager); ServerAcceptThread(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager);
virtual ~ServerAcceptThread(); virtual ~ServerAcceptThread();
// Set the parameters. // Set the parameters.
void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd, const std::string &logDir); void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd, const std::string &logDir, boost::shared_ptr<IrcThread> ircThread);
ServerCallback &GetCallback(); ServerCallback &GetCallback();
GuiInterface &GetGui(); 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);
protected: protected:
// Main function of the thread. // Main function of the thread.
@@ -64,6 +76,9 @@ private:
boost::shared_ptr<ServerLobbyThread> m_lobbyThread; boost::shared_ptr<ServerLobbyThread> m_lobbyThread;
GuiInterface &m_gui; GuiInterface &m_gui;
std::string m_ircNick;
boost::shared_ptr<IrcThread> m_ircThread;
}; };
#endif #endif
+5
View File
@@ -50,6 +50,7 @@ public:
const std::string &GetName() const; const std::string &GetName() const;
void AddSession(SessionWrapper session); void AddSession(SessionWrapper session);
void KickPlayer(unsigned playerId);
ServerCallback &GetCallback(); ServerCallback &GetCallback();
GameState GetCurRound() const; GameState GetCurRound() const;
@@ -80,6 +81,7 @@ protected:
// Main function of the thread. // Main function of the thread.
virtual void Main(); virtual void Main();
void KickPlayerLoop();
void InternalStartGame(); void InternalStartGame();
void ResetGame(); void ResetGame();
@@ -129,6 +131,9 @@ private:
PlayerDataList m_computerPlayerList; PlayerDataList m_computerPlayerList;
mutable boost::mutex m_computerPlayerListMutex; mutable boost::mutex m_computerPlayerListMutex;
PlayerIdList m_kickPlayerList;
mutable boost::mutex m_kickPlayerListMutex;
unsigned m_adminPlayerId; unsigned m_adminPlayerId;
mutable boost::mutex m_adminPlayerIdMutex; mutable boost::mutex m_adminPlayerIdMutex;
+11 -1
View File
@@ -31,7 +31,8 @@
#include <list> #include <list>
#include <core/boost/timers.hpp> #include <core/boost/timers.hpp>
#define LOBBY_THREAD_TERMINATE_TIMEOUT 20000 #define LOBBY_THREAD_TERMINATE_TIMEOUT_MSEC 20000
#define ADMIN_IRC_TERMINATE_TIMEOUT_MSEC 2000
class SenderThread; class SenderThread;
@@ -65,6 +66,8 @@ public:
void HandleGameRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket); void HandleGameRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket);
void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket); void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket);
bool KickPlayerByName(const std::string &playerName);
void AddComputerPlayer(boost::shared_ptr<PlayerData> player); void AddComputerPlayer(boost::shared_ptr<PlayerData> player);
void RemoveComputerPlayer(boost::shared_ptr<PlayerData> player); void RemoveComputerPlayer(boost::shared_ptr<PlayerData> player);
@@ -76,6 +79,8 @@ public:
AvatarManager &GetAvatarManager(); AvatarManager &GetAvatarManager();
ServerStats GetStats() const;
protected: protected:
typedef std::deque<boost::shared_ptr<ConnectData> > ConnectQueue; typedef std::deque<boost::shared_ptr<ConnectData> > ConnectQueue;
@@ -105,10 +110,12 @@ protected:
void NewSessionLoop(); void NewSessionLoop();
void CloseSessionLoop(); void CloseSessionLoop();
void RemoveGameLoop(); void RemoveGameLoop();
void KickPlayerLoop();
void CleanupAvatarCache(); void CleanupAvatarCache();
void InternalAddGame(boost::shared_ptr<ServerGameThread> game); void InternalAddGame(boost::shared_ptr<ServerGameThread> game);
void InternalRemoveGame(boost::shared_ptr<ServerGameThread> game); void InternalRemoveGame(boost::shared_ptr<ServerGameThread> game);
void InternalKickPlayer(unsigned playerId);
void TerminateGames(); void TerminateGames();
@@ -160,6 +167,9 @@ private:
RemoveGameList m_removeGameList; RemoveGameList m_removeGameList;
mutable boost::mutex m_removeGameListMutex; mutable boost::mutex m_removeGameListMutex;
PlayerIdList m_kickPlayerList;
mutable boost::mutex m_kickPlayerListMutex;
PlayerDataMap m_computerPlayers; PlayerDataMap m_computerPlayers;
mutable boost::mutex m_computerPlayersMutex; mutable boost::mutex m_computerPlayersMutex;
+34 -16
View File
@@ -39,7 +39,7 @@
using namespace std; using namespace std;
Session::Session(GuiInterface *g, ConfigFile *c) Session::Session(GuiInterface *g, ConfigFile *c)
: currentGameNum(0), myNetClient(NULL), myNetServer(NULL), myIrcThread(NULL), : currentGameNum(0), myNetClient(NULL), myNetServer(NULL), myClientIrcThread(NULL),
myGui(g), myConfig(c), myGameType(GAME_TYPE_NONE) myGui(g), myConfig(c), myGameType(GAME_TYPE_NONE)
{ {
} }
@@ -139,7 +139,7 @@ boost::shared_ptr<AvatarManager> Session::getAvatarManager()
void Session::startInternetClient() void Session::startInternetClient()
{ {
if (myNetClient || myIrcThread || !myGui) if (myNetClient || myClientIrcThread || !myGui)
{ {
assert(false); assert(false);
return; return;
@@ -148,14 +148,15 @@ void Session::startInternetClient()
if (myConfig->readConfigInt("UseIRCLobbyChat")) if (myConfig->readConfigInt("UseIRCLobbyChat"))
{ {
myIrcThread = new IrcThread(*myGui); myClientIrcThread = new IrcThread(*myGui);
myIrcThread->Init( myClientIrcThread->Init(
myConfig->readConfigString("IRCServerAddress"), myConfig->readConfigString("IRCServerAddress"),
myConfig->readConfigInt("IRCServerPort"), myConfig->readConfigInt("IRCServerPort"),
myConfig->readConfigInt("IRCServerUseIpv6") == 1, myConfig->readConfigInt("IRCServerUseIpv6") == 1,
myIrcNick, myIrcNick,
myConfig->readConfigString("IRCChannel")); myConfig->readConfigString("IRCChannel"),
myIrcThread->Run(); myConfig->readConfigString("IRCChannelPassword"));
myClientIrcThread->Run();
} }
myNetClient = new ClientThread(*myGui, *myAvatarManager); myNetClient = new ClientThread(*myGui, *myAvatarManager);
@@ -221,17 +222,17 @@ void Session::terminateNetworkClient()
if (!myNetClient) if (!myNetClient)
return; // already terminated return; // already terminated
myNetClient->SignalTermination(); myNetClient->SignalTermination();
if (myIrcThread) if (myClientIrcThread)
myIrcThread->SignalTermination(); myClientIrcThread->SignalTermination();
// Give the threads some time to terminate. // Give the threads some time to terminate.
if (myNetClient->Join(NET_CLIENT_TERMINATE_TIMEOUT_MSEC)) if (myNetClient->Join(NET_CLIENT_TERMINATE_TIMEOUT_MSEC))
delete myNetClient; delete myNetClient;
if (myIrcThread && myIrcThread->Join(NET_IRC_TERMINATE_TIMEOUT_MSEC)) if (myClientIrcThread && myClientIrcThread->Join(NET_IRC_TERMINATE_TIMEOUT_MSEC))
delete myIrcThread; delete myClientIrcThread;
// If termination fails, leave a memory leak to prevent a crash. // If termination fails, leave a memory leak to prevent a crash.
myNetClient = 0; myNetClient = 0;
myIrcThread = 0; myClientIrcThread = 0;
myGameType = GAME_TYPE_NONE; myGameType = GAME_TYPE_NONE;
} }
@@ -256,13 +257,32 @@ void Session::startNetworkServer()
assert(false); assert(false);
return; return;
} }
myNetServer = new ServerAcceptThread(*myGui, myConfig, *myAvatarManager); myNetServer = new ServerAcceptThread(*myGui, myConfig, *myAvatarManager);
boost::shared_ptr<IrcThread> tmpIrcThread;
if (myConfig->readConfigInt("UseAdminIRC"))
{
tmpIrcThread = boost::shared_ptr<IrcThread>(new IrcThread(*myNetServer));
tmpIrcThread->Init(
myConfig->readConfigString("AdminIRCServerAddress"),
myConfig->readConfigInt("AdminIRCServerPort"),
myConfig->readConfigInt("AdminIRCServerUseIpv6") == 1,
myConfig->readConfigString("AdminIRCServerNick"),
myConfig->readConfigString("AdminIRCChannel"),
myConfig->readConfigString("AdminIRCChannelPassword"));
}
myNetServer->Init( myNetServer->Init(
myConfig->readConfigInt("ServerPort"), myConfig->readConfigInt("ServerPort"),
myConfig->readConfigInt("ServerUseIpv6") == 1, myConfig->readConfigInt("ServerUseIpv6") == 1,
myConfig->readConfigInt("ServerUseSctp") == 1, myConfig->readConfigInt("ServerUseSctp") == 1,
myConfig->readConfigString("ServerPassword"), myConfig->readConfigString("ServerPassword"),
myConfig->readConfigString("LogDir")); myConfig->readConfigString("LogDir"),
tmpIrcThread
);
myNetServer->Run(); myNetServer->Run();
} }
@@ -273,9 +293,7 @@ void Session::terminateNetworkServer()
myNetServer->SignalTermination(); myNetServer->SignalTermination();
// Give the thread some time to terminate. // Give the thread some time to terminate.
if (myNetServer->Join(NET_SERVER_TERMINATE_TIMEOUT_MSEC)) if (myNetServer->Join(NET_SERVER_TERMINATE_TIMEOUT_MSEC))
{
delete myNetServer; delete myNetServer;
}
// If termination fails, leave a memory leak to prevent a crash. // If termination fails, leave a memory leak to prevent a crash.
myNetServer = 0; myNetServer = 0;
} }
@@ -299,9 +317,9 @@ bool Session::waitForNetworkServer(unsigned timeoutMsec)
void Session::sendIrcChatMessage(const std::string &message) void Session::sendIrcChatMessage(const std::string &message)
{ {
if (!myIrcThread) if (!myClientIrcThread)
return; return;
myIrcThread->SendChatMessage(message); myClientIrcThread->SendChatMessage(message);
} }
void Session::sendLeaveCurrentGame() void Session::sendLeaveCurrentGame()
+2 -1
View File
@@ -96,7 +96,8 @@ private:
ClientThread *myNetClient; ClientThread *myNetClient;
ServerAcceptThread *myNetServer; ServerAcceptThread *myNetServer;
IrcThread *myIrcThread; IrcThread *myClientIrcThread;
boost::shared_ptr<AvatarManager> myAvatarManager; boost::shared_ptr<AvatarManager> myAvatarManager;
boost::shared_ptr<Game> currentGame; boost::shared_ptr<Game> currentGame;