diff --git a/pokerth_lib.pro b/pokerth_lib.pro index 0df05b54..ae6aac46 100644 --- a/pokerth_lib.pro +++ b/pokerth_lib.pro @@ -78,6 +78,7 @@ HEADERS += \ src/net/servergame.h \ src/net/servergamestate.h \ src/net/serverlobbythread.h \ + src/net/serverbanmanager.h \ src/net/servercallback.h \ src/net/sessiondata.h \ src/net/sessiondatacallback.h \ @@ -175,6 +176,7 @@ SOURCES += \ src/net/common/servergame.cpp \ src/net/common/servergamestate.cpp \ src/net/common/serverlobbythread.cpp \ + src/net/common/serverbanmanager.cpp \ src/net/common/servercallback.cpp \ src/net/common/sessiondata.cpp \ src/net/common/sessiondatacallback.cpp \ diff --git a/src/net/common/serverbanmanager.cpp b/src/net/common/serverbanmanager.cpp new file mode 100644 index 00000000..6a7316d9 --- /dev/null +++ b/src/net/common/serverbanmanager.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include + +using namespace std; + + +ServerBanManager::ServerBanManager() +: m_curBanId(0) +{ +} + +ServerBanManager::~ServerBanManager() +{ +} + +void +ServerBanManager::BanPlayerRegex(const string &playerRegex) +{ + boost::mutex::scoped_lock lock(m_banMutex); + m_banPlayerNameMap[GetNextBanId()] = boost::regex(playerRegex, boost::regex_constants::no_except); +} + +void +ServerBanManager::BanIPAddress(const string &ipAddress) +{ + boost::mutex::scoped_lock lock(m_banMutex); + m_banIPAddressMap[GetNextBanId()] = ipAddress; +} + +bool +ServerBanManager::UnBan(unsigned banId) +{ + bool retVal = false; + boost::mutex::scoped_lock lock(m_banMutex); + RegexMap::iterator posNick = m_banPlayerNameMap.find(banId); + if (posNick != m_banPlayerNameMap.end()) + { + m_banPlayerNameMap.erase(posNick); + retVal = true; + } + else + { + IPAddressMap::iterator posIP = m_banIPAddressMap.find(banId); + if (posIP != m_banIPAddressMap.end()) + { + m_banIPAddressMap.erase(posIP); + retVal = true; + } + } + return retVal; +} + +void +ServerBanManager::GetBanList(list &list) const +{ + boost::mutex::scoped_lock lock(m_banMutex); + RegexMap::const_iterator i_nick = m_banPlayerNameMap.begin(); + RegexMap::const_iterator end_nick = m_banPlayerNameMap.end(); + while (i_nick != end_nick) + { + ostringstream banText; + banText << (*i_nick).first << ": (nick) - " << (*i_nick).second.str(); + list.push_back(banText.str()); + ++i_nick; + } + IPAddressMap::const_iterator i_ip = m_banIPAddressMap.begin(); + IPAddressMap::const_iterator end_ip = m_banIPAddressMap.end(); + while (i_ip != end_ip) + { + ostringstream banText; + banText << (*i_ip).first << ": (IP) - " << (*i_ip).second; + list.push_back(banText.str()); + ++i_ip; + } +} + +void +ServerBanManager::ClearBanList() +{ + boost::mutex::scoped_lock lock(m_banMutex); + m_banPlayerNameMap.clear(); + m_banIPAddressMap.clear(); +} + +bool +ServerBanManager::IsPlayerBanned(const std::string &name) const +{ + bool retVal = false; + boost::mutex::scoped_lock lock(m_banMutex); + RegexMap::const_iterator i = m_banPlayerNameMap.begin(); + RegexMap::const_iterator end = m_banPlayerNameMap.end(); + while (i != end) + { + if (regex_match(name, (*i).second)) + { + retVal = true; + break; + } + ++i; + } + + return retVal; +} + +bool +ServerBanManager::IsIPAddressBanned(const std::string &ipAddress) const +{ + bool retVal = false; + boost::mutex::scoped_lock lock(m_banMutex); + IPAddressMap::const_iterator i = m_banIPAddressMap.begin(); + IPAddressMap::const_iterator end = m_banIPAddressMap.end(); + while (i != end) + { + if (ipAddress == (*i).second) + { + retVal = true; + break; + } + ++i; + } + + return retVal; +} + +unsigned +ServerBanManager::GetNextBanId() +{ + m_curBanId++; + if (m_curBanId == 0) // 0 is an invalid id. + m_curBanId++; + + return m_curBanId; +} + diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 286d84ed..2d5cc8fc 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -89,7 +90,7 @@ private: ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager, boost::shared_ptr ioService) -: m_ioService(ioService), m_curBanId(0), m_gui(gui), m_avatarManager(avatarManager), +: m_ioService(ioService), m_gui(gui), m_avatarManager(avatarManager), m_playerConfig(playerConfig), m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1), m_statDataChanged(false), m_removeGameTimer(*ioService), m_removePlayerTimer(*ioService), m_sessionTimeoutTimer(*ioService), m_avatarCleanupTimer(*ioService), @@ -99,6 +100,7 @@ ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig m_senderCallback.reset(new ServerSenderCallback(*this)); m_sender.reset(new SenderHelper(*m_senderCallback, m_ioService)); m_receiver.reset(new ReceiverHelper); + m_banManager.reset(new ServerBanManager); } ServerLobbyThread::~ServerLobbyThread() @@ -327,75 +329,6 @@ ServerLobbyThread::KickPlayerByName(const std::string &playerName) return retVal; } -void -ServerLobbyThread::BanPlayerRegex(const string &playerRegex) -{ - boost::mutex::scoped_lock lock(m_banMutex); - m_banPlayerNameMap[++m_curBanId] = boost::regex(playerRegex, boost::regex_constants::no_except); -} - -void -ServerLobbyThread::BanIPAddress(const string &ipAddress) -{ - boost::mutex::scoped_lock lock(m_banMutex); - m_banIPAddressMap[++m_curBanId] = ipAddress; -} - -bool -ServerLobbyThread::UnBan(unsigned banId) -{ - bool retVal = false; - boost::mutex::scoped_lock lock(m_banMutex); - RegexMap::iterator posNick = m_banPlayerNameMap.find(banId); - if (posNick != m_banPlayerNameMap.end()) - { - m_banPlayerNameMap.erase(posNick); - retVal = true; - } - else - { - IPAddressMap::iterator posIP = m_banIPAddressMap.find(banId); - if (posIP != m_banIPAddressMap.end()) - { - m_banIPAddressMap.erase(posIP); - retVal = true; - } - } - return retVal; -} - -void -ServerLobbyThread::GetBanList(list &list) const -{ - boost::mutex::scoped_lock lock(m_banMutex); - RegexMap::const_iterator i_nick = m_banPlayerNameMap.begin(); - RegexMap::const_iterator end_nick = m_banPlayerNameMap.end(); - while (i_nick != end_nick) - { - ostringstream banText; - banText << (*i_nick).first << ": (nick) - " << (*i_nick).second.str(); - list.push_back(banText.str()); - ++i_nick; - } - IPAddressMap::const_iterator i_ip = m_banIPAddressMap.begin(); - IPAddressMap::const_iterator end_ip = m_banIPAddressMap.end(); - while (i_ip != end_ip) - { - ostringstream banText; - banText << (*i_ip).first << ": (IP) - " << (*i_ip).second; - list.push_back(banText.str()); - ++i_ip; - } -} - -void -ServerLobbyThread::ClearBanList() -{ - boost::mutex::scoped_lock lock(m_banMutex); - m_banPlayerNameMap.clear(); - m_banIPAddressMap.clear(); -} - string ServerLobbyThread::GetPlayerIPAddress(const std::string &playerName) const { @@ -485,6 +418,13 @@ ServerLobbyThread::GetIOService() return *m_ioService; } +ServerBanManager & +ServerLobbyThread::GetBanManager() +{ + assert(m_banManager); + return *m_banManager; +} + u_int32_t ServerLobbyThread::GetNextUniquePlayerId() { @@ -733,13 +673,13 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn } // Check whether the player name is banned. - if (IsPlayerBanned(initData.playerName)) + if (GetBanManager().IsPlayerBanned(initData.playerName)) { SessionError(session, ERR_NET_PLAYER_BANNED); return; } // Check whether the peer IP address is banned. - if (IsIPAddressBanned(session.sessionData->GetClientAddr())) + if (GetBanManager().IsIPAddressBanned(session.sessionData->GetClientAddr())) { SessionError(session, ERR_NET_PLAYER_BANNED); return; @@ -1517,46 +1457,6 @@ ServerLobbyThread::IsPlayerConnected(const string &name) const return retVal; } -bool -ServerLobbyThread::IsPlayerBanned(const std::string &name) const -{ - bool retVal = false; - boost::mutex::scoped_lock lock(m_banMutex); - RegexMap::const_iterator i = m_banPlayerNameMap.begin(); - RegexMap::const_iterator end = m_banPlayerNameMap.end(); - while (i != end) - { - if (regex_match(name, (*i).second)) - { - retVal = true; - break; - } - ++i; - } - - return retVal; -} - -bool -ServerLobbyThread::IsIPAddressBanned(const std::string &ipAddress) const -{ - bool retVal = false; - boost::mutex::scoped_lock lock(m_banMutex); - IPAddressMap::const_iterator i = m_banIPAddressMap.begin(); - IPAddressMap::const_iterator end = m_banIPAddressMap.end(); - while (i != end) - { - if (ipAddress == (*i).second) - { - retVal = true; - break; - } - ++i; - } - - return retVal; -} - boost::shared_ptr ServerLobbyThread::CreateNetPacketGameListNew(const ServerGame &game) { diff --git a/src/net/common/servermanager.cpp b/src/net/common/servermanager.cpp index 0f41992d..a8e8f896 100644 --- a/src/net/common/servermanager.cpp +++ b/src/net/common/servermanager.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -132,7 +133,7 @@ ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string & string playerRegex(msgStream.str().substr(msgStream.tellg())); if (!playerRegex.empty()) { - GetLobbyThread().BanPlayerRegex(playerRegex); + GetLobbyThread().GetBanManager().BanPlayerRegex(playerRegex); m_ircThread->SendChatMessage(nickName + ": The regex \"" + playerRegex + "\" was added to the player ban list."); } } @@ -143,14 +144,14 @@ ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string & string ipAddress(msgStream.str().substr(msgStream.tellg())); if (!ipAddress.empty()) { - GetLobbyThread().BanIPAddress(ipAddress); + GetLobbyThread().GetBanManager().BanIPAddress(ipAddress); m_ircThread->SendChatMessage(nickName + ": The IP address \"" + ipAddress + "\" was added to the IP address ban list."); } } else if (command == "listban") { list banList; - GetLobbyThread().GetBanList(banList); + GetLobbyThread().GetBanManager().GetBanList(banList); list::const_iterator i = banList.begin(); list::const_iterator end = banList.end(); while (i != end) @@ -167,14 +168,14 @@ ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string & { unsigned banId = 0; msgStream >> banId; - if (GetLobbyThread().UnBan(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().ClearBanList(); + GetLobbyThread().GetBanManager().ClearBanList(); m_ircThread->SendChatMessage(nickName + ": All ban lists were cleared."); } else if (command == "stat") diff --git a/src/net/serverbanmanager.h b/src/net/serverbanmanager.h new file mode 100644 index 00000000..c54c8cb6 --- /dev/null +++ b/src/net/serverbanmanager.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +/* Manager for server bans. */ + +#ifndef _SERVERBANMANAGER_H_ +#define _SERVERBANMANAGER_H_ + +#include +#include +#include +#include + +class ServerBanManager +{ +public: + ServerBanManager(); + virtual ~ServerBanManager(); + + void BanPlayerRegex(const std::string &playerRegex); + void BanIPAddress(const std::string &ipAddress); + bool UnBan(unsigned banId); + void GetBanList(std::list &list) const; + void ClearBanList(); + + bool IsPlayerBanned(const std::string &name) const; + bool IsIPAddressBanned(const std::string &ipAddress) const; + +protected: + typedef std::map RegexMap; + typedef std::map IPAddressMap; + + unsigned GetNextBanId(); + +private: + RegexMap m_banPlayerNameMap; + IPAddressMap m_banIPAddressMap; + unsigned m_curBanId; + mutable boost::mutex m_banMutex; +}; + +#endif diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index 8f85a277..200268ed 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -40,6 +39,7 @@ class SenderHelper; class ReceiverHelper; class ServerSenderCallback; class ServerGame; +class ServerBanManager; class ConfigFile; class AvatarManager; struct GameData; @@ -71,11 +71,6 @@ public: void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket); bool KickPlayerByName(const std::string &playerName); - void BanPlayerRegex(const std::string &playerRegex); - void BanIPAddress(const std::string &ipAddress); - bool UnBan(unsigned banId); - void GetBanList(std::list &list) const; - void ClearBanList(); std::string GetPlayerIPAddress(const std::string &playerName) const; void RemovePlayer(unsigned playerId, unsigned errorCode); @@ -96,6 +91,7 @@ public: SenderHelper &GetSender(); boost::asio::io_service &GetIOService(); + ServerBanManager &GetBanManager(); protected: @@ -107,8 +103,6 @@ protected: typedef std::map > GameMap; typedef std::map TimerClientAddressMap; typedef std::list RemoveGameList; - typedef std::map RegexMap; - typedef std::map IPAddressMap; // Main function of the thread. virtual void Main(); @@ -164,8 +158,6 @@ protected: GuiInterface &GetGui(); bool IsPlayerConnected(const std::string &name) const; - bool IsPlayerBanned(const std::string &name) const; - bool IsIPAddressBanned(const std::string &ipAddress) const; static boost::shared_ptr CreateNetPacketGameListNew(const ServerGame &game); static boost::shared_ptr CreateNetPacketGameListUpdate(unsigned gameId, GameMode mode); @@ -193,11 +185,6 @@ private: PlayerDataMap m_computerPlayers; mutable boost::mutex m_computerPlayersMutex; - RegexMap m_banPlayerNameMap; - IPAddressMap m_banIPAddressMap; - unsigned m_curBanId; - mutable boost::mutex m_banMutex; - GameMap m_gameMap; GuiInterface &m_gui; @@ -216,6 +203,8 @@ private: bool m_statDataChanged; mutable boost::mutex m_statMutex; + boost::shared_ptr m_banManager; + boost::asio::deadline_timer m_removeGameTimer; boost::asio::deadline_timer m_removePlayerTimer; boost::asio::deadline_timer m_sessionTimeoutTimer;