diff --git a/src/config/configfile.cpp b/src/config/configfile.cpp index eaa2a184..5bc0d6de 100644 --- a/src/config/configfile.cpp +++ b/src/config/configfile.cpp @@ -50,7 +50,7 @@ ConfigFile::ConfigFile(char *argv0, bool readonly) : noWriteAccess(readonly) myConfigState = OK; // !!!! Revisionsnummer der Configdefaults !!!!! - configRev = 89; + configRev = 90; //standard defaults logOnOffDefault = "1"; @@ -203,7 +203,8 @@ ConfigFile::ConfigFile(char *argv0, bool readonly) : noWriteAccess(readonly) configList.push_back(ConfigInfo("ServerPutAvatarsUser", CONFIG_TYPE_STRING, "")); configList.push_back(ConfigInfo("ServerPutAvatarsPassword", CONFIG_TYPE_STRING, "")); configList.push_back(ConfigInfo("ServerDoNotAutoKickSmallDelaySec", CONFIG_TYPE_STRING, "10")); - configList.push_back(ConfigInfo("InternetServerConfigMode", CONFIG_TYPE_INT, "0")); + configList.push_back(ConfigInfo("ServerBruteForceProtection", CONFIG_TYPE_INT, "1")); + configList.push_back(ConfigInfo("InternetServerConfigMode", CONFIG_TYPE_INT, "0")); configList.push_back(ConfigInfo("InternetServerListAddress", CONFIG_TYPE_STRING, "pokerth.net/serverlist.xml.z")); configList.push_back(ConfigInfo("InternetServerAddress", CONFIG_TYPE_STRING, "pokerth.6dns.org")); configList.push_back(ConfigInfo("InternetServerPort", CONFIG_TYPE_INT, "7234")); diff --git a/src/net/clientthread.h b/src/net/clientthread.h index d40329e8..0218601f 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -72,6 +72,7 @@ public: void SendPlayerAction(); void SendGameChatMessage(const std::string &msg); void SendLobbyChatMessage(const std::string &msg); + void SendPrivateChatMessage(unsigned targetPlayerId, const std::string &msg); void SendJoinFirstGame(const std::string &password); void SendJoinGame(unsigned gameId, const std::string &password); void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password); diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index 765af861..06d13600 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -209,6 +209,25 @@ ClientThread::SendLobbyChatMessage(const std::string &msg) m_ioService->post(boost::bind(&ClientThread::SendSessionPacket, shared_from_this(), packet)); } +void +ClientThread::SendPrivateChatMessage(unsigned targetPlayerId, const std::string &msg) +{ + // Warning: This function is called in the context of the GUI thread. + // Create a network packet containing the chat message. + boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); + packet->GetMsg()->present = PokerTHMessage_PR_chatRequestMessage; + ChatRequestMessage_t *netChat = &packet->GetMsg()->choice.chatRequestMessage; + OCTET_STRING_fromBuf(&netChat->chatText, + msg.c_str(), + msg.length()); + + netChat->chatRequestType.present = chatRequestType_PR_chatRequestTypePrivate; + netChat->chatRequestType.choice.chatRequestTypePrivate.targetPlayerId = targetPlayerId; + + // Just dump the packet. + m_ioService->post(boost::bind(&ClientThread::SendSessionPacket, shared_from_this(), packet)); +} + void ClientThread::SendJoinFirstGame(const std::string &password) { diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 4017faf4..586f80dc 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -270,7 +270,8 @@ AbstractServerGameStateReceiving::ProcessPacket(boost::shared_ptr se // Forward chat text to all players. // TODO: Some limitation needed. ChatRequestMessage_t *netChatRequest = &packet->GetMsg()->choice.chatRequestMessage; - if (netChatRequest->chatRequestType.present == chatRequestType_PR_chatRequestTypeLobby) + if (netChatRequest->chatRequestType.present == chatRequestType_PR_chatRequestTypeLobby + || netChatRequest->chatRequestType.present == chatRequestType_PR_chatRequestTypePrivate) { if (!server->IsRunning()) server->GetLobbyThread().HandleChatRequest(session, *netChatRequest); diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 29924b71..8cb7ac63 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -253,7 +253,7 @@ ServerLobbyThread::AddConnection(boost::shared_ptr sock) netAnnounce->latestGameVersion.major = POKERTH_VERSION_MAJOR; netAnnounce->latestGameVersion.minor = POKERTH_VERSION_MINOR; netAnnounce->latestBetaRevision = POKERTH_BETA_REVISION; - switch (m_mode) + switch (GetServerMode()) { case SERVER_MODE_LAN: netAnnounce->serverType = serverType_serverTypeLAN; @@ -996,18 +996,21 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const InitMessage // Before any other processing, perform some denial of service and // brute force attack prevention by checking whether the user recently sent an // Init packet. - bool recentlySentInit = false; + if (m_serverConfig->readConfigInt("ServerBruteForceProtection") != 0) { - boost::mutex::scoped_lock lock(m_timerClientAddressMapMutex); - if (m_timerClientAddressMap.find(session.sessionData->GetClientAddr()) != m_timerClientAddressMap.end()) - recentlySentInit = true; - else - m_timerClientAddressMap[session.sessionData->GetClientAddr()] = boost::timers::portable::microsec_timer(); - } - if (recentlySentInit) - { - SessionError(session, ERR_NET_INIT_BLOCKED); - return; + bool recentlySentInit = false; + { + boost::mutex::scoped_lock lock(m_timerClientAddressMapMutex); + if (m_timerClientAddressMap.find(session.sessionData->GetClientAddr()) != m_timerClientAddressMap.end()) + recentlySentInit = true; + else + m_timerClientAddressMap[session.sessionData->GetClientAddr()] = boost::timers::portable::microsec_timer(); + } + if (recentlySentInit) + { + SessionError(session, ERR_NET_INIT_BLOCKED); + return; + } } // Check the protocol version. @@ -1414,35 +1417,66 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const std::st void ServerLobbyThread::HandleNetPacketChatRequest(SessionWrapper session, const ChatRequestMessage_t &chatRequest) { - if (chatRequest.chatRequestType.present == chatRequestType_PR_chatRequestTypeLobby - && session.playerData - && session.playerData->GetRights() != PLAYER_RIGHTS_GUEST) // Guests are not allowed to chat. + // Guests are not allowed to chat. + if (session.playerData && session.playerData->GetRights() != PLAYER_RIGHTS_GUEST) { - boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); - packet->GetMsg()->present = PokerTHMessage_PR_chatMessage; - ChatMessage_t *netChat = &packet->GetMsg()->choice.chatMessage; - netChat->chatType.present = chatType_PR_chatTypeLobby; - ChatTypeLobby_t *netLobbyChat = &netChat->chatType.choice.chatTypeLobby; - netLobbyChat->playerId = session.playerData->GetUniqueId(); - OCTET_STRING_fromBuf( - &netChat->chatText, - (char *)chatRequest.chatText.buf, - chatRequest.chatText.size); + if (chatRequest.chatRequestType.present == chatRequestType_PR_chatRequestTypeLobby) + { + boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); + packet->GetMsg()->present = PokerTHMessage_PR_chatMessage; + ChatMessage_t *netChat = &packet->GetMsg()->choice.chatMessage; + netChat->chatType.present = chatType_PR_chatTypeLobby; + ChatTypeLobby_t *netLobbyChat = &netChat->chatType.choice.chatTypeLobby; + netLobbyChat->playerId = session.playerData->GetUniqueId(); + OCTET_STRING_fromBuf( + &netChat->chatText, + (char *)chatRequest.chatText.buf, + chatRequest.chatText.size); - m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established); - m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game); + m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established); + m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game); - string chatMsg = STL_STRING_FROM_OCTET_STRING(chatRequest.chatText); - // Send the message to the chat cleaner bot. - m_chatCleanerManager->HandleChatText( - session.playerData->GetUniqueId(), - session.playerData->GetName(), - chatMsg); - // Send the message to the irc bot. - GetIrcBotCallback().SignalLobbyMessage( - session.playerData->GetUniqueId(), - session.playerData->GetName(), - chatMsg); + string chatMsg = STL_STRING_FROM_OCTET_STRING(chatRequest.chatText); + // Send the message to the chat cleaner bot. + m_chatCleanerManager->HandleChatText( + session.playerData->GetUniqueId(), + session.playerData->GetName(), + chatMsg); + // Send the message to the irc bot. + GetIrcBotCallback().SignalLobbyMessage( + session.playerData->GetUniqueId(), + session.playerData->GetName(), + chatMsg); + } + else if (chatRequest.chatRequestType.present == chatRequestType_PR_chatRequestTypePrivate) + { + const ChatRequestTypePrivate_t *netPrivateChat = &chatRequest.chatRequestType.choice.chatRequestTypePrivate; + SessionWrapper targetSession = m_sessionManager.GetSessionByUniquePlayerId(netPrivateChat->targetPlayerId); + if (!targetSession.sessionData) + targetSession = m_gameSessionManager.GetSessionByUniquePlayerId(netPrivateChat->targetPlayerId); + + if (targetSession.sessionData && targetSession.playerData) + { + // Only allow private messages to players which are not in running games. + // TODO: Send chat reject message if private message was not sent. + unsigned gameId = targetSession.sessionData->GetGameId(); + GameMap::const_iterator pos = m_gameMap.find(gameId); + if (pos == m_gameMap.end() || !pos->second->IsRunning()) + { + boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); + packet->GetMsg()->present = PokerTHMessage_PR_chatMessage; + ChatMessage_t *netChat = &packet->GetMsg()->choice.chatMessage; + netChat->chatType.present = chatType_PR_chatTypeLobby; + ChatTypeLobby_t *netLobbyChat = &netChat->chatType.choice.chatTypeLobby; + netLobbyChat->playerId = session.playerData->GetUniqueId(); + OCTET_STRING_fromBuf( + &netChat->chatText, + (char *)chatRequest.chatText.buf, + chatRequest.chatText.size); + GetSender().Send(targetSession.sessionData, packet); + } + } + } } } diff --git a/src/session.cpp b/src/session.cpp index 31bd92d0..77ffcc35 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -379,6 +379,14 @@ void Session::sendLobbyChatMessage(const std::string &message) myNetClient->SendLobbyChatMessage(message); } +void Session::sendPrivateChatMessage(unsigned targetPlayerId, const std::string &message) +{ + if (!myNetClient) + return; + myNetClient->SendPrivateChatMessage(targetPlayerId, message); +} + + void Session::kickPlayer(unsigned playerId) { if (!myNetClient) diff --git a/src/session.h b/src/session.h index 79adb76d..fbef4742 100755 --- a/src/session.h +++ b/src/session.h @@ -80,6 +80,7 @@ public: void sendGameChatMessage(const std::string &message); void sendLobbyChatMessage(const std::string &message); + void sendPrivateChatMessage(unsigned targetPlayerId, const std::string &message); void kickPlayer(unsigned playerId); void kickPlayer(const std::string &playerName); void startVoteKickPlayer(unsigned playerId);