diff --git a/src/net/common/serverbanmanager.cpp b/src/net/common/serverbanmanager.cpp index 05638fbc..09e0b9b4 100644 --- a/src/net/common/serverbanmanager.cpp +++ b/src/net/common/serverbanmanager.cpp @@ -32,10 +32,15 @@ ServerBanManager::~ServerBanManager() } void -ServerBanManager::BanPlayerRegex(const string &playerRegex) +ServerBanManager::BanPlayerRegex(const string &playerRegex, unsigned durationHours) { boost::mutex::scoped_lock lock(m_banMutex); - m_banPlayerNameMap[GetNextBanId()] = boost::regex(playerRegex, boost::regex_constants::no_except); + unsigned banId = GetNextBanId(); + + TimedPlayerBan tmpBan; + tmpBan.timer = InternalRegisterTimedBan(banId, durationHours); + tmpBan.nameRegex = boost::regex(playerRegex, boost::regex_constants::no_except); + m_banPlayerNameMap[banId] = tmpBan; } void @@ -43,14 +48,11 @@ ServerBanManager::BanIPAddress(const string &ipAddress, unsigned durationHours) { boost::mutex::scoped_lock lock(m_banMutex); unsigned banId = GetNextBanId(); - boost::shared_ptr tmpItem(new TimedIPAddress(ipAddress, *m_ioService)); - tmpItem->timer.expires_from_now( - boost::posix_time::hours(durationHours)); - tmpItem->timer.async_wait( - boost::bind( - &ServerBanManager::TimerRemoveIPBan, shared_from_this(), boost::asio::placeholders::error, banId, tmpItem)); - m_banIPAddressMap[banId] = tmpItem; + TimedIPBan tmpBan; + tmpBan.timer = InternalRegisterTimedBan(banId, durationHours); + tmpBan.ipAddress = ipAddress; + m_banIPAddressMap[banId] = tmpBan; } bool @@ -61,6 +63,8 @@ ServerBanManager::UnBan(unsigned banId) RegexMap::iterator posNick = m_banPlayerNameMap.find(banId); if (posNick != m_banPlayerNameMap.end()) { + if (posNick->second.timer) + posNick->second.timer->cancel(); m_banPlayerNameMap.erase(posNick); retVal = true; } @@ -69,7 +73,8 @@ ServerBanManager::UnBan(unsigned banId) IPAddressMap::iterator posIP = m_banIPAddressMap.find(banId); if (posIP != m_banIPAddressMap.end()) { - posIP->second->timer.cancel(); + if (posIP->second.timer) + posIP->second.timer->cancel(); m_banIPAddressMap.erase(posIP); retVal = true; } @@ -86,7 +91,9 @@ ServerBanManager::GetBanList(list &list) const while (i_nick != end_nick) { ostringstream banText; - banText << (*i_nick).first << ": (nick) - " << (*i_nick).second.str(); + banText << (*i_nick).first << ": (nick) - " << (*i_nick).second.nameRegex.str(); + if ((*i_nick).second.timer) + banText << " duration: " << (*i_nick).second.timer->expires_from_now().hours() << "h"; list.push_back(banText.str()); ++i_nick; } @@ -95,7 +102,9 @@ ServerBanManager::GetBanList(list &list) const while (i_ip != end_ip) { ostringstream banText; - banText << (*i_ip).first << ": (IP) - " << (*i_ip).second->ipAddress << " duration: " << (*i_ip).second->timer.expires_from_now().hours() << "h"; + banText << (*i_ip).first << ": (IP) - " << (*i_ip).second.ipAddress; + if ((*i_ip).second.timer) + banText << " duration: " << (*i_ip).second.timer->expires_from_now().hours() << "h"; list.push_back(banText.str()); ++i_ip; } @@ -118,7 +127,7 @@ ServerBanManager::IsPlayerBanned(const std::string &name) const RegexMap::const_iterator end = m_banPlayerNameMap.end(); while (i != end) { - if (regex_match(name, (*i).second)) + if (regex_match(name, (*i).second.nameRegex)) { retVal = true; break; @@ -138,7 +147,7 @@ ServerBanManager::IsIPAddressBanned(const std::string &ipAddress) const IPAddressMap::const_iterator end = m_banIPAddressMap.end(); while (i != end) { - if (ipAddress == (*i).second->ipAddress) + if (ipAddress == (*i).second.ipAddress) { retVal = true; break; @@ -149,11 +158,27 @@ ServerBanManager::IsIPAddressBanned(const std::string &ipAddress) const return retVal; } -void -ServerBanManager::TimerRemoveIPBan(const boost::system::error_code &ec, unsigned timerId, boost::shared_ptr item) +boost::shared_ptr +ServerBanManager::InternalRegisterTimedBan(unsigned timerId, unsigned durationHours) { - if (!ec && item) - UnBan(timerId); + boost::shared_ptr tmpTimer; + if (durationHours) + { + tmpTimer.reset(new boost::asio::deadline_timer(*m_ioService)); + tmpTimer->expires_from_now( + boost::posix_time::hours(durationHours)); + tmpTimer->async_wait( + boost::bind( + &ServerBanManager::TimerRemoveBan, shared_from_this(), boost::asio::placeholders::error, timerId, tmpTimer)); + } + return tmpTimer; +} + +void +ServerBanManager::TimerRemoveBan(const boost::system::error_code &ec, unsigned banId, boost::shared_ptr timer) +{ + if (!ec && timer) + UnBan(banId); } unsigned diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 4581aa1a..4b45e390 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -106,7 +106,12 @@ public: virtual void SignalBanPlayer(unsigned playerId) { - // TODO + string playerName(m_server.GetPlayerNameFromId(playerId)); + if (!playerName.empty()) + { + m_server.GetBanManager().BanPlayerRegex(playerName, 1); + m_server.RemovePlayer(playerId, ERR_NET_PLAYER_KICKED); + } } virtual void ConnectSuccess() @@ -492,15 +497,29 @@ ServerLobbyThread::GetPlayerIPAddress(const std::string &playerName) const { string ipAddress; SessionWrapper session = m_sessionManager.GetSessionByPlayerName(playerName); - if (!session.sessionData.get()) + if (!session.sessionData) session = m_gameSessionManager.GetSessionByPlayerName(playerName); - if (session.sessionData.get() && session.playerData.get()) + if (session.sessionData && session.playerData) ipAddress = session.sessionData->GetClientAddr(); return ipAddress; } +std::string +ServerLobbyThread::GetPlayerNameFromId(unsigned playerId) const +{ + string name; + SessionWrapper session = m_sessionManager.GetSessionByUniquePlayerId(playerId); + if (!session.sessionData) + session = m_gameSessionManager.GetSessionByUniquePlayerId(playerId); + + if (session.sessionData && session.playerData) + name = session.playerData->GetName(); + + return name; +} + void ServerLobbyThread::RemovePlayer(unsigned playerId, unsigned errorCode) { diff --git a/src/net/serverbanmanager.h b/src/net/serverbanmanager.h index cac8d9c8..3421623d 100644 --- a/src/net/serverbanmanager.h +++ b/src/net/serverbanmanager.h @@ -34,7 +34,7 @@ public: ServerBanManager(boost::shared_ptr ioService); virtual ~ServerBanManager(); - void BanPlayerRegex(const std::string &playerRegex); + void BanPlayerRegex(const std::string &playerRegex, unsigned durationHours = 0); void BanIPAddress(const std::string &ipAddress, unsigned durationHours); bool UnBan(unsigned banId); void GetBanList(std::list &list) const; @@ -44,20 +44,24 @@ public: bool IsIPAddressBanned(const std::string &ipAddress) const; protected: - struct TimedIPAddress + struct TimedPlayerBan { - TimedIPAddress(const std::string &i, boost::asio::io_service &s) - : ipAddress(i), timer(s) {} + boost::shared_ptr timer; + boost::regex nameRegex; + }; + struct TimedIPBan + { + boost::shared_ptr timer; std::string ipAddress; - boost::asio::deadline_timer timer; }; - void TimerRemoveIPBan(const boost::system::error_code &ec, unsigned timerId, boost::shared_ptr item); + boost::shared_ptr InternalRegisterTimedBan(unsigned timerId, unsigned durationHours); + void TimerRemoveBan(const boost::system::error_code &ec, unsigned banId, boost::shared_ptr timer); boost::shared_ptr m_ioService; - typedef std::map RegexMap; - typedef std::map > IPAddressMap; + typedef std::map RegexMap; + typedef std::map IPAddressMap; unsigned GetNextBanId(); diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index e52c5c8f..b418bf18 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -80,8 +80,10 @@ public: bool KickPlayerByName(const std::string &playerName); std::string GetPlayerIPAddress(const std::string &playerName) const; + std::string GetPlayerNameFromId(unsigned playerId) const; void RemovePlayer(unsigned playerId, unsigned errorCode); + void SendGlobalChat(const std::string &message); void SendGlobalMsgBox(const std::string &message); void SendChatBotMsg(const std::string &message);