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:
@@ -53,7 +53,7 @@ ConfigFile::ConfigFile(int argc, char **argv) : noWriteAccess(0)
|
||||
if(strcmp(argv[i], "--nowriteaccess") == 0) { noWriteAccess = 1; }
|
||||
}
|
||||
// !!!! Revisionsnummer der Configdefaults !!!!!
|
||||
configRev = 51;
|
||||
configRev = 52;
|
||||
|
||||
//standard defaults
|
||||
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("IRCChannelPassword", CONFIG_TYPE_STRING, ""));
|
||||
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("MyAvatar", CONFIG_TYPE_STRING, ""));
|
||||
configList.push_back(ConfigInfo("Opponent1Name", CONFIG_TYPE_STRING, "Player 1"));
|
||||
|
||||
+4
-4
@@ -70,12 +70,12 @@ enum Button {
|
||||
struct ServerStats
|
||||
{
|
||||
ServerStats()
|
||||
: numberOfPlayersOnServer(0), totalPlayersEverLoggedIn(0), totalGamesEverStarted(0),
|
||||
maxGamesRunning(0), maxPlayersLoggedIn(0) {}
|
||||
: numberOfPlayersOnServer(0), totalPlayersEverLoggedIn(0), totalGamesEverCreated(0),
|
||||
maxGamesOpen(0), maxPlayersLoggedIn(0) {}
|
||||
unsigned numberOfPlayersOnServer;
|
||||
unsigned totalPlayersEverLoggedIn;
|
||||
unsigned totalGamesEverStarted;
|
||||
unsigned maxGamesRunning;
|
||||
unsigned totalGamesEverCreated;
|
||||
unsigned maxGamesOpen;
|
||||
unsigned maxPlayersLoggedIn;
|
||||
};
|
||||
|
||||
|
||||
@@ -956,8 +956,8 @@ ClientThread::UpdateStatData(const ServerStats &stats)
|
||||
if (stats.totalPlayersEverLoggedIn)
|
||||
m_curStats.totalPlayersEverLoggedIn = stats.totalPlayersEverLoggedIn;
|
||||
|
||||
if (stats.totalGamesEverStarted)
|
||||
m_curStats.totalGamesEverStarted = stats.totalGamesEverStarted;
|
||||
if (stats.totalGamesEverCreated)
|
||||
m_curStats.totalGamesEverCreated = stats.totalGamesEverCreated;
|
||||
|
||||
GetCallback().SignalNetClientStatsUpdate(m_curStats);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ struct IrcContext
|
||||
bool useIPv6;
|
||||
string nick;
|
||||
string channel;
|
||||
string channelPassword;
|
||||
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);
|
||||
|
||||
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
|
||||
@@ -259,7 +260,7 @@ IrcThread::~IrcThread()
|
||||
}
|
||||
|
||||
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())
|
||||
return; // TODO: throw exception
|
||||
@@ -271,6 +272,7 @@ IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6
|
||||
context.useIPv6 = ipv6;
|
||||
context.nick = nick;
|
||||
context.channel = channel;
|
||||
context.channelPassword = channelPassword;
|
||||
|
||||
// Initialize libirc stuff.
|
||||
irc_callbacks_t callbacks;
|
||||
|
||||
@@ -4092,7 +4092,7 @@ NetPacketStatisticsChanged::SetData(const NetPacketStatisticsChanged::Data &inDa
|
||||
++numValues;
|
||||
if (inData.stats.totalPlayersEverLoggedIn)
|
||||
++numValues;
|
||||
if (inData.stats.totalGamesEverStarted)
|
||||
if (inData.stats.totalGamesEverCreated)
|
||||
++numValues;
|
||||
|
||||
// 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;
|
||||
}
|
||||
if (inData.stats.totalGamesEverStarted)
|
||||
if (inData.stats.totalGamesEverCreated)
|
||||
{
|
||||
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.
|
||||
@@ -4148,7 +4148,7 @@ NetPacketStatisticsChanged::GetData(NetPacketStatisticsChanged::Data &outData) c
|
||||
outData.stats.totalPlayersEverLoggedIn = ntohl(curStatisticsData->statisticsValue);
|
||||
break;
|
||||
case NET_STAT_TOTAL_GAMES_EVER_ON_SERVER:
|
||||
outData.stats.totalGamesEverStarted = ntohl(curStatisticsData->statisticsValue);
|
||||
outData.stats.totalGamesEverCreated = ntohl(curStatisticsData->statisticsValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <net/serveracceptthread.h>
|
||||
#include <net/servercontext.h>
|
||||
#include <net/ircthread.h>
|
||||
#include <net/connectdata.h>
|
||||
#include <net/serverlobbythread.h>
|
||||
#include <net/socket_helper.h>
|
||||
@@ -27,6 +28,8 @@
|
||||
#include <net/socket_startup.h>
|
||||
#include <core/loghelper.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#define ACCEPT_TIMEOUT_MSEC 50
|
||||
#define NET_SERVER_LISTEN_BACKLOG 5
|
||||
|
||||
@@ -44,7 +47,7 @@ ServerAcceptThread::~ServerAcceptThread()
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
@@ -61,6 +64,7 @@ ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const string
|
||||
context.SetServerPort(serverPort);
|
||||
|
||||
GetLobbyThread().Init(pwd, logDir);
|
||||
m_ircThread = ircThread;
|
||||
}
|
||||
|
||||
ServerCallback &
|
||||
@@ -75,12 +79,75 @@ ServerAcceptThread::GetGui()
|
||||
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
|
||||
ServerAcceptThread::Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
Listen();
|
||||
if (m_ircThread)
|
||||
m_ircThread->Run();
|
||||
GetLobbyThread().Run();
|
||||
|
||||
while (!ShouldTerminate() && !GetLobbyThread().Join(0))
|
||||
@@ -94,7 +161,13 @@ ServerAcceptThread::Main()
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
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
|
||||
|
||||
@@ -87,6 +87,13 @@ ServerGameThread::AddSession(SessionWrapper session)
|
||||
m_sessionQueue.push_back(session);
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::KickPlayer(unsigned playerId)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_kickPlayerListMutex);
|
||||
m_kickPlayerList.push_back(playerId);
|
||||
}
|
||||
|
||||
GameState
|
||||
ServerGameThread::GetCurRound() const
|
||||
{
|
||||
@@ -141,6 +148,7 @@ ServerGameThread::Main()
|
||||
}
|
||||
// Process current state.
|
||||
GetState().Process(*this);
|
||||
KickPlayerLoop();
|
||||
} while (!ShouldTerminate() && GetSessionManager().HasSessions());
|
||||
} catch (const PokerTHException &e)
|
||||
{
|
||||
@@ -155,6 +163,25 @@ ServerGameThread::Main()
|
||||
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
|
||||
ServerGameThread::InternalStartGame()
|
||||
{
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
|
||||
#define SERVER_STATISTICS_FILE_NAME "server_statistics.log"
|
||||
#define SERVER_STATISTICS_STR_TOTAL_PLAYERS "TotalNumPlayersLoggedIn"
|
||||
#define SERVER_STATISTICS_STR_TOTAL_GAMES "TotalNumGamesStarted"
|
||||
#define SERVER_STATISTICS_STR_MAX_GAMES "MaxGamesRunning"
|
||||
#define SERVER_STATISTICS_STR_TOTAL_GAMES "TotalNumGamesCreated"
|
||||
#define SERVER_STATISTICS_STR_MAX_GAMES "MaxGamesOpen"
|
||||
#define SERVER_STATISTICS_STR_MAX_PLAYERS "MaxPlayersLoggedIn"
|
||||
|
||||
using namespace std;
|
||||
@@ -201,14 +201,6 @@ ServerLobbyThread::NotifyStartingGame(unsigned gameId)
|
||||
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED);
|
||||
m_sessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Established);
|
||||
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
|
||||
@@ -233,6 +225,24 @@ ServerLobbyThread::HandleGameRetrieveAvatar(SessionWrapper session, const NetPac
|
||||
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
|
||||
ServerLobbyThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
|
||||
{
|
||||
@@ -260,6 +270,13 @@ ServerLobbyThread::GetAvatarManager()
|
||||
return m_avatarManager;
|
||||
}
|
||||
|
||||
ServerStats
|
||||
ServerLobbyThread::GetStats() const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_statMutex);
|
||||
return m_statData;
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
ServerLobbyThread::GetNextUniquePlayerId()
|
||||
{
|
||||
@@ -293,6 +310,8 @@ ServerLobbyThread::Main()
|
||||
CloseSessionLoop();
|
||||
// Remove games.
|
||||
RemoveGameLoop();
|
||||
// Kick players.
|
||||
KickPlayerLoop();
|
||||
// Cleanup cache.
|
||||
CleanupAvatarCache();
|
||||
// Save statistics if needed.
|
||||
@@ -773,6 +792,22 @@ ServerLobbyThread::RemoveGameLoop()
|
||||
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
|
||||
ServerLobbyThread::CleanupAvatarCache()
|
||||
{
|
||||
@@ -794,6 +829,15 @@ ServerLobbyThread::InternalAddGame(boost::shared_ptr<ServerGameThread> game)
|
||||
// Notify all players.
|
||||
m_sessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established);
|
||||
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
|
||||
@@ -809,6 +853,31 @@ ServerLobbyThread::InternalRemoveGame(boost::shared_ptr<ServerGameThread> 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
|
||||
ServerLobbyThread::TerminateGames()
|
||||
{
|
||||
@@ -982,11 +1051,11 @@ ServerLobbyThread::ReadStatisticsFile()
|
||||
if (statisticsType == SERVER_STATISTICS_STR_TOTAL_PLAYERS)
|
||||
m_statData.totalPlayersEverLoggedIn = statisticsValue;
|
||||
else if (statisticsType == SERVER_STATISTICS_STR_TOTAL_GAMES)
|
||||
m_statData.totalGamesEverStarted = statisticsValue;
|
||||
m_statData.totalGamesEverCreated = statisticsValue;
|
||||
else if (statisticsType == SERVER_STATISTICS_STR_MAX_PLAYERS)
|
||||
m_statData.maxPlayersLoggedIn = statisticsValue;
|
||||
else if (statisticsType == SERVER_STATISTICS_STR_MAX_GAMES)
|
||||
m_statData.maxGamesRunning = statisticsValue;
|
||||
m_statData.maxGamesOpen = statisticsValue;
|
||||
} while (!i.fail() && !i.eof());
|
||||
m_statDataChanged = false;
|
||||
}
|
||||
@@ -1005,9 +1074,9 @@ ServerLobbyThread::SaveStatisticsFile()
|
||||
if (!o.fail())
|
||||
{
|
||||
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_GAMES " " << m_statData.maxGamesRunning << endl;
|
||||
o << SERVER_STATISTICS_STR_MAX_GAMES " " << m_statData.maxGamesOpen << endl;
|
||||
m_statDataChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public:
|
||||
virtual ~IrcThread();
|
||||
|
||||
// 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.
|
||||
void SendChatMessage(const std::string &msg);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <game_defs.h>
|
||||
#include <core/thread.h>
|
||||
|
||||
#include <gui/guiinterface.h>
|
||||
#include <string>
|
||||
|
||||
@@ -32,20 +33,31 @@ class ServerSenderCallback;
|
||||
class SenderThread;
|
||||
class ConfigFile;
|
||||
class AvatarManager;
|
||||
class IrcThread;
|
||||
struct GameData;
|
||||
|
||||
class ServerAcceptThread : public Thread
|
||||
class ServerAcceptThread : public Thread, public IrcCallback
|
||||
{
|
||||
public:
|
||||
ServerAcceptThread(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager);
|
||||
virtual ~ServerAcceptThread();
|
||||
|
||||
// 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();
|
||||
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:
|
||||
|
||||
// Main function of the thread.
|
||||
@@ -64,6 +76,9 @@ private:
|
||||
boost::shared_ptr<ServerLobbyThread> m_lobbyThread;
|
||||
|
||||
GuiInterface &m_gui;
|
||||
|
||||
std::string m_ircNick;
|
||||
boost::shared_ptr<IrcThread> m_ircThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
const std::string &GetName() const;
|
||||
|
||||
void AddSession(SessionWrapper session);
|
||||
void KickPlayer(unsigned playerId);
|
||||
|
||||
ServerCallback &GetCallback();
|
||||
GameState GetCurRound() const;
|
||||
@@ -80,6 +81,7 @@ protected:
|
||||
|
||||
// Main function of the thread.
|
||||
virtual void Main();
|
||||
void KickPlayerLoop();
|
||||
|
||||
void InternalStartGame();
|
||||
void ResetGame();
|
||||
@@ -129,6 +131,9 @@ private:
|
||||
PlayerDataList m_computerPlayerList;
|
||||
mutable boost::mutex m_computerPlayerListMutex;
|
||||
|
||||
PlayerIdList m_kickPlayerList;
|
||||
mutable boost::mutex m_kickPlayerListMutex;
|
||||
|
||||
unsigned m_adminPlayerId;
|
||||
mutable boost::mutex m_adminPlayerIdMutex;
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
#include <list>
|
||||
#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;
|
||||
@@ -65,6 +66,8 @@ public:
|
||||
void HandleGameRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket);
|
||||
void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket);
|
||||
|
||||
bool KickPlayerByName(const std::string &playerName);
|
||||
|
||||
void AddComputerPlayer(boost::shared_ptr<PlayerData> player);
|
||||
void RemoveComputerPlayer(boost::shared_ptr<PlayerData> player);
|
||||
|
||||
@@ -76,6 +79,8 @@ public:
|
||||
|
||||
AvatarManager &GetAvatarManager();
|
||||
|
||||
ServerStats GetStats() const;
|
||||
|
||||
protected:
|
||||
|
||||
typedef std::deque<boost::shared_ptr<ConnectData> > ConnectQueue;
|
||||
@@ -105,10 +110,12 @@ protected:
|
||||
void NewSessionLoop();
|
||||
void CloseSessionLoop();
|
||||
void RemoveGameLoop();
|
||||
void KickPlayerLoop();
|
||||
void CleanupAvatarCache();
|
||||
|
||||
void InternalAddGame(boost::shared_ptr<ServerGameThread> game);
|
||||
void InternalRemoveGame(boost::shared_ptr<ServerGameThread> game);
|
||||
void InternalKickPlayer(unsigned playerId);
|
||||
|
||||
void TerminateGames();
|
||||
|
||||
@@ -160,6 +167,9 @@ private:
|
||||
RemoveGameList m_removeGameList;
|
||||
mutable boost::mutex m_removeGameListMutex;
|
||||
|
||||
PlayerIdList m_kickPlayerList;
|
||||
mutable boost::mutex m_kickPlayerListMutex;
|
||||
|
||||
PlayerDataMap m_computerPlayers;
|
||||
mutable boost::mutex m_computerPlayersMutex;
|
||||
|
||||
|
||||
+34
-16
@@ -39,7 +39,7 @@
|
||||
using namespace std;
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
@@ -139,7 +139,7 @@ boost::shared_ptr<AvatarManager> Session::getAvatarManager()
|
||||
|
||||
void Session::startInternetClient()
|
||||
{
|
||||
if (myNetClient || myIrcThread || !myGui)
|
||||
if (myNetClient || myClientIrcThread || !myGui)
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
@@ -148,14 +148,15 @@ void Session::startInternetClient()
|
||||
|
||||
if (myConfig->readConfigInt("UseIRCLobbyChat"))
|
||||
{
|
||||
myIrcThread = new IrcThread(*myGui);
|
||||
myIrcThread->Init(
|
||||
myClientIrcThread = new IrcThread(*myGui);
|
||||
myClientIrcThread->Init(
|
||||
myConfig->readConfigString("IRCServerAddress"),
|
||||
myConfig->readConfigInt("IRCServerPort"),
|
||||
myConfig->readConfigInt("IRCServerUseIpv6") == 1,
|
||||
myIrcNick,
|
||||
myConfig->readConfigString("IRCChannel"));
|
||||
myIrcThread->Run();
|
||||
myConfig->readConfigString("IRCChannel"),
|
||||
myConfig->readConfigString("IRCChannelPassword"));
|
||||
myClientIrcThread->Run();
|
||||
}
|
||||
|
||||
myNetClient = new ClientThread(*myGui, *myAvatarManager);
|
||||
@@ -221,17 +222,17 @@ void Session::terminateNetworkClient()
|
||||
if (!myNetClient)
|
||||
return; // already terminated
|
||||
myNetClient->SignalTermination();
|
||||
if (myIrcThread)
|
||||
myIrcThread->SignalTermination();
|
||||
if (myClientIrcThread)
|
||||
myClientIrcThread->SignalTermination();
|
||||
// Give the threads some time to terminate.
|
||||
if (myNetClient->Join(NET_CLIENT_TERMINATE_TIMEOUT_MSEC))
|
||||
delete myNetClient;
|
||||
if (myIrcThread && myIrcThread->Join(NET_IRC_TERMINATE_TIMEOUT_MSEC))
|
||||
delete myIrcThread;
|
||||
if (myClientIrcThread && myClientIrcThread->Join(NET_IRC_TERMINATE_TIMEOUT_MSEC))
|
||||
delete myClientIrcThread;
|
||||
|
||||
// If termination fails, leave a memory leak to prevent a crash.
|
||||
myNetClient = 0;
|
||||
myIrcThread = 0;
|
||||
myClientIrcThread = 0;
|
||||
myGameType = GAME_TYPE_NONE;
|
||||
}
|
||||
|
||||
@@ -256,13 +257,32 @@ void Session::startNetworkServer()
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
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(
|
||||
myConfig->readConfigInt("ServerPort"),
|
||||
myConfig->readConfigInt("ServerUseIpv6") == 1,
|
||||
myConfig->readConfigInt("ServerUseSctp") == 1,
|
||||
myConfig->readConfigString("ServerPassword"),
|
||||
myConfig->readConfigString("LogDir"));
|
||||
myConfig->readConfigString("LogDir"),
|
||||
tmpIrcThread
|
||||
);
|
||||
|
||||
myNetServer->Run();
|
||||
}
|
||||
|
||||
@@ -273,9 +293,7 @@ void Session::terminateNetworkServer()
|
||||
myNetServer->SignalTermination();
|
||||
// Give the thread some time to terminate.
|
||||
if (myNetServer->Join(NET_SERVER_TERMINATE_TIMEOUT_MSEC))
|
||||
{
|
||||
delete myNetServer;
|
||||
}
|
||||
// If termination fails, leave a memory leak to prevent a crash.
|
||||
myNetServer = 0;
|
||||
}
|
||||
@@ -299,9 +317,9 @@ bool Session::waitForNetworkServer(unsigned timeoutMsec)
|
||||
|
||||
void Session::sendIrcChatMessage(const std::string &message)
|
||||
{
|
||||
if (!myIrcThread)
|
||||
if (!myClientIrcThread)
|
||||
return;
|
||||
myIrcThread->SendChatMessage(message);
|
||||
myClientIrcThread->SendChatMessage(message);
|
||||
}
|
||||
|
||||
void Session::sendLeaveCurrentGame()
|
||||
|
||||
+2
-1
@@ -96,7 +96,8 @@ private:
|
||||
|
||||
ClientThread *myNetClient;
|
||||
ServerAcceptThread *myNetServer;
|
||||
IrcThread *myIrcThread;
|
||||
IrcThread *myClientIrcThread;
|
||||
|
||||
boost::shared_ptr<AvatarManager> myAvatarManager;
|
||||
|
||||
boost::shared_ptr<Game> currentGame;
|
||||
|
||||
Reference in New Issue
Block a user