diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 56e55b24..aa49349e 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -80,7 +81,7 @@ private: ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager) -: m_gui(gui), m_avatarManager(avatarManager), m_playerConfig(playerConfig), +: m_curBanId(0), m_gui(gui), m_avatarManager(avatarManager), m_playerConfig(playerConfig), m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1), m_statDataChanged(false), m_startTime(boost::posix_time::second_clock::local_time()) { @@ -258,17 +259,46 @@ ServerLobbyThread::KickPlayerByName(const std::string &playerName) } void -ServerLobbyThread::BanPlayerRegex(const std::string &playerRegex) +ServerLobbyThread::BanPlayerRegex(const string &playerRegex) { - boost::mutex::scoped_lock lock(m_banPlayerNameListMutex); - m_banPlayerNameList.push_back(boost::regex(playerRegex, boost::regex_constants::no_except)); + boost::mutex::scoped_lock lock(m_banMutex); + m_banPlayerNameMap[++m_curBanId] = boost::regex(playerRegex, boost::regex_constants::no_except); +} + +bool +ServerLobbyThread::UnBanPlayerRegex(unsigned banId) +{ + bool retVal = false; + boost::mutex::scoped_lock lock(m_banMutex); + RegexMap::iterator pos = m_banPlayerNameMap.find(banId); + if (pos != m_banPlayerNameMap.end()) + { + m_banPlayerNameMap.erase(pos); + retVal = true; + } + return retVal; } void -ServerLobbyThread::ClearBanList() +ServerLobbyThread::GetBanPlayerList(list &list) const { - boost::mutex::scoped_lock lock(m_banPlayerNameListMutex); - m_banPlayerNameList.clear(); + boost::mutex::scoped_lock lock(m_banMutex); + RegexMap::const_iterator i = m_banPlayerNameMap.begin(); + RegexMap::const_iterator end = m_banPlayerNameMap.end(); + while (i != end) + { + ostringstream banText; + banText << (*i).first << ": " << (*i).second.str(); + list.push_back(banText.str()); + ++i; + } +} + +void +ServerLobbyThread::ClearBanPlayerList() +{ + boost::mutex::scoped_lock lock(m_banMutex); + m_banPlayerNameMap.clear(); } void @@ -1381,12 +1411,12 @@ bool ServerLobbyThread::IsPlayerBanned(const std::string &name) const { bool retVal = false; - boost::mutex::scoped_lock lock(m_banPlayerNameListMutex); - RegexList::const_iterator i = m_banPlayerNameList.begin(); - RegexList::const_iterator end = m_banPlayerNameList.end(); + 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)) + if (regex_match(name, (*i).second)) { retVal = true; break; diff --git a/src/net/common/servermanager.cpp b/src/net/common/servermanager.cpp index a5d0dddb..14f7cade 100644 --- a/src/net/common/servermanager.cpp +++ b/src/net/common/servermanager.cpp @@ -90,107 +90,134 @@ ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string & { if (m_ircThread) { - istringstream msgStream(msg); - string target; - msgStream >> target; - if (boost::algorithm::iequals(target, m_ircNick + ":")) + try { - string command; - msgStream >> command; - if (command == "kick") + istringstream msgStream(msg); + string target; + msgStream >> target; + if (boost::algorithm::iequals(target, m_ircNick + ":")) { - while (msgStream.peek() == ' ') - msgStream.get(); - string playerName(msgStream.str().substr(msgStream.tellg())); - if (!playerName.empty()) + string command; + msgStream >> command; + if (command == "kick") { - if (GetLobbyThread().KickPlayerByName(playerName)) - m_ircThread->SendChatMessage(nickName + ": Successfully kicked player \"" + playerName + "\" from the server."); + while (msgStream.peek() == ' ') + msgStream.get(); + string playerName(msgStream.str().substr(msgStream.tellg())); + 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 == "nickban") + { + while (msgStream.peek() == ' ') + msgStream.get(); + string playerRegex(msgStream.str().substr(msgStream.tellg())); + if (!playerRegex.empty()) + { + GetLobbyThread().BanPlayerRegex(playerRegex); + m_ircThread->SendChatMessage(nickName + ": The regex \"" + playerRegex + "\" was added to the player ban list."); + } + } + else if (command == "listnickban") + { + list banList; + GetLobbyThread().GetBanPlayerList(banList); + list::const_iterator i = banList.begin(); + list::const_iterator end = banList.end(); + while (i != end) + { + m_ircThread->SendChatMessage(*i); + ++i; + } + } + else if (command == "removenickban") + { + unsigned banId = 0; + msgStream >> banId; + if (GetLobbyThread().UnBanPlayerRegex(banId)) + m_ircThread->SendChatMessage(nickName + ": The nick ban was successfully removed."); else - m_ircThread->SendChatMessage(nickName + ": Player \"" + playerName + "\" was not found on the server."); + m_ircThread->SendChatMessage(nickName + ": This nick ban does not exist."); } - } - else if (command == "ban") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string playerRegex(msgStream.str().substr(msgStream.tellg())); - if (!playerRegex.empty()) + else if (command == "clearnickban") { - GetLobbyThread().BanPlayerRegex(playerRegex); - m_ircThread->SendChatMessage(nickName + ": The regex \"" + playerRegex + "\" was added to the player ban list."); + GetLobbyThread().ClearBanPlayerList(); + m_ircThread->SendChatMessage(nickName + ": The player ban list was cleared."); } - } - else if (command == "clearban") - { - GetLobbyThread().ClearBanList(); - m_ircThread->SendChatMessage(nickName + ": The player ban list was cleared."); - } - else if (command == "stat") - { - ServerStats tmpStats = GetLobbyThread().GetStats(); + else if (command == "stat") { - boost::posix_time::time_duration timeDiff(boost::posix_time::second_clock::local_time() - GetLobbyThread().GetStartTime()); - ostringstream statStream; - statStream - << "Server uptime................ " << timeDiff.hours() / 24 << " days " << timeDiff.hours() % 24 << " hours " << timeDiff.minutes() << " minutes " << timeDiff.seconds() << " seconds"; - m_ircThread->SendChatMessage(statStream.str()); + ServerStats tmpStats = GetLobbyThread().GetStats(); + { + boost::posix_time::time_duration timeDiff(boost::posix_time::second_clock::local_time() - GetLobbyThread().GetStartTime()); + ostringstream statStream; + statStream + << "Server uptime................ " << timeDiff.hours() / 24 << " days " << timeDiff.hours() % 24 << " hours " << timeDiff.minutes() << " minutes " << timeDiff.seconds() << " seconds"; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Players currently on Server.. " << tmpStats.numberOfPlayersOnServer; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Games currently open......... " << tmpStats.numberOfGamesOpen; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Total players ever logged in. " << tmpStats.totalPlayersEverLoggedIn + << " (Max at a time: " << tmpStats.maxPlayersLoggedIn << ")"; + m_ircThread->SendChatMessage(statStream.str()); + } + { + ostringstream statStream; + statStream + << "Total games ever open........ " << tmpStats.totalGamesEverCreated + << " (Max at a time: " << tmpStats.maxGamesOpen << ")"; + m_ircThread->SendChatMessage(statStream.str()); + } } + else if (command == "chat") { - ostringstream statStream; - statStream - << "Players currently on Server.. " << tmpStats.numberOfPlayersOnServer; - m_ircThread->SendChatMessage(statStream.str()); + while (msgStream.peek() == ' ') + msgStream.get(); + string chat(msgStream.str().substr(msgStream.tellg())); + if (!chat.empty() && chat.size() < MAX_CHAT_TEXT_SIZE) + { + GetLobbyThread().SendGlobalChat(chat); + m_ircThread->SendChatMessage(nickName + ": Global chat message sent."); + } + else + m_ircThread->SendChatMessage(nickName + ": Invalid message."); } + else if (command == "msg") { - ostringstream statStream; - statStream - << "Games currently open......... " << tmpStats.numberOfGamesOpen; - m_ircThread->SendChatMessage(statStream.str()); - } - { - ostringstream statStream; - statStream - << "Total players ever logged in. " << tmpStats.totalPlayersEverLoggedIn - << " (Max at a time: " << tmpStats.maxPlayersLoggedIn << ")"; - m_ircThread->SendChatMessage(statStream.str()); - } - { - ostringstream statStream; - statStream - << "Total games ever open........ " << tmpStats.totalGamesEverCreated - << " (Max at a time: " << tmpStats.maxGamesOpen << ")"; - m_ircThread->SendChatMessage(statStream.str()); - } - } - else if (command == "chat") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string chat(msgStream.str().substr(msgStream.tellg())); - if (!chat.empty() && chat.size() < MAX_CHAT_TEXT_SIZE) - { - GetLobbyThread().SendGlobalChat(chat); - m_ircThread->SendChatMessage(nickName + ": Global chat message sent."); + while (msgStream.peek() == ' ') + msgStream.get(); + string message(msgStream.str().substr(msgStream.tellg())); + if (!message.empty() && message.size() < MAX_CHAT_TEXT_SIZE) + { + GetLobbyThread().SendGlobalMsgBox(message); + m_ircThread->SendChatMessage(nickName + ": Global message box sent."); + } + else + m_ircThread->SendChatMessage(nickName + ": Invalid message."); } else - m_ircThread->SendChatMessage(nickName + ": Invalid message."); + m_ircThread->SendChatMessage(nickName + ": Invalid command \"" + command + "\"."); } - else if (command == "msg") - { - while (msgStream.peek() == ' ') - msgStream.get(); - string message(msgStream.str().substr(msgStream.tellg())); - if (!message.empty() && message.size() < MAX_CHAT_TEXT_SIZE) - { - GetLobbyThread().SendGlobalMsgBox(message); - m_ircThread->SendChatMessage(nickName + ": Global message box sent."); - } - else - m_ircThread->SendChatMessage(nickName + ": Invalid message."); - } - else - m_ircThread->SendChatMessage(nickName + ": Invalid command \"" + command + "\"."); + } catch (...) + { + m_ircThread->SendChatMessage(nickName + ": Syntax error. Please check the command."); } } } diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index 1194bc04..8c9df591 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -70,7 +70,9 @@ public: bool KickPlayerByName(const std::string &playerName); void BanPlayerRegex(const std::string &playerRegex); - void ClearBanList(); + bool UnBanPlayerRegex(unsigned banId); + void GetBanPlayerList(std::list &list) const; + void ClearBanPlayerList(); void RemovePlayer(unsigned playerId, unsigned errorCode); void SendGlobalChat(const std::string &message); @@ -102,7 +104,7 @@ protected: typedef std::map > GameMap; typedef std::map TimerClientAddressMap; typedef std::list RemoveGameList; - typedef std::list RegexList; + typedef std::map RegexMap; // Main function of the thread. virtual void Main(); @@ -192,8 +194,9 @@ private: SessionIdList m_resubscribeList; mutable boost::mutex m_resubscribeListMutex; - RegexList m_banPlayerNameList; - mutable boost::mutex m_banPlayerNameListMutex; + RegexMap m_banPlayerNameMap; + unsigned m_curBanId; + mutable boost::mutex m_banMutex; GameMap m_gameMap;