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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user