/***************************************************************************** * PokerTH - The open source texas holdem engine * * Copyright (C) 2006-2011 Felix Hammer, Florian Thauer, Lothar May * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see . * *****************************************************************************/ /* Network server lobby thread. */ #ifndef _SERVERLOBBYTHREAD_H_ #define _SERVERLOBBYTHREAD_H_ #include #include #include #include #include #include #include #include #define NET_LOBBY_THREAD_TERMINATE_TIMEOUT_MSEC 20000 #define NET_ADMIN_IRC_TERMINATE_TIMEOUT_MSEC 4000 class SenderHelper; class InternalServerCallback; class ServerIrcBotCallback; class ServerGame; class ServerBanManager; class ConfigFile; class AvatarManager; class ChatCleanerManager; class ServerDBInterface; struct GameData; class Game; struct Gsasl; class ServerLobbyThread : public Thread, public boost::enable_shared_from_this { public: ServerLobbyThread(GuiInterface &gui, ServerMode mode, ServerIrcBotCallback &ircBotCb, ConfigFile &serverConfig, AvatarManager &avatarManager, boost::shared_ptr ioService); virtual ~ServerLobbyThread(); void Init(const std::string &logDir); virtual void SignalTermination(); void AddConnection(boost::shared_ptr sock); void ReAddSession(boost::shared_ptr session, int reason, unsigned gameId); void MoveSessionToGame(boost::shared_ptr game, boost::shared_ptr session, bool autoLeave); void SessionError(boost::shared_ptr session, int errorCode); void ResubscribeLobbyMsg(boost::shared_ptr session); void NotifyPlayerJoinedLobby(unsigned playerId); void NotifyPlayerLeftLobby(unsigned playerId); void NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId); void NotifyPlayerLeftGame(unsigned gameId, unsigned playerId); void NotifyGameAdminChanged(unsigned gameId, unsigned newAdminPlayerId); void NotifyStartingGame(unsigned gameId); void NotifyReopeningGame(unsigned gameId); void DispatchPacket(boost::shared_ptr session, boost::shared_ptr packet); void HandleGameRetrievePlayerInfo(boost::shared_ptr session, const PlayerInfoRequestMessage_t &playerInfoRequest); void HandleGameRetrieveAvatar(boost::shared_ptr session, const AvatarRequestMessage_t &retrieveAvatar); void HandleGameReportGame(boost::shared_ptr session, const ReportGameMessage_t &reportGame); void HandleChatRequest(boost::shared_ptr session, const ChatRequestMessage_t &chatRequest); bool KickPlayerByName(const std::string &playerName); bool RemoveGameByPlayerName(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 MutePlayerInGame(unsigned playerId); void SendGlobalChat(const std::string &message); void SendGlobalMsgBox(const std::string &message); void SendChatBotMsg(const std::string &message); void SendChatBotMsg(unsigned gameId, const std::string &message); void ReconnectChatBot(); void AddComputerPlayer(boost::shared_ptr player); void RemoveComputerPlayer(boost::shared_ptr player); bool SendToLobbyPlayer(unsigned playerId, boost::shared_ptr packet); u_int32_t GetNextUniquePlayerId(); u_int32_t GetNextGameId(); ServerCallback &GetCallback(); AvatarManager &GetAvatarManager(); ChatCleanerManager &GetChatCleaner(); ServerStats GetStats() const; boost::posix_time::ptime GetStartTime() const; ServerMode GetServerMode() const; SenderHelper &GetSender(); boost::asio::io_service &GetIOService(); boost::shared_ptr GetDatabase(); ServerBanManager &GetBanManager(); protected: typedef std::deque > ConnectQueue; typedef std::list > SessionList; typedef std::list SessionIdList; typedef std::map TimerSessionMap; typedef std::map > GameMap; typedef std::map TimerClientAddressMap; typedef std::list RemoveGameList; // Main function of the thread. virtual void Main(); void RegisterTimers(); void CancelTimers(); void InitAuthContext(); void ClearAuthContext(); void InitChatCleaner(); void HandlePacket(boost::shared_ptr session, boost::shared_ptr packet); void HandleNetPacketInit(boost::shared_ptr session, const InitMessage_t &initMessage); void HandleNetPacketAuthClientResponse(boost::shared_ptr session, const AuthClientResponse_t &clientResponse); void HandleNetPacketAvatarHeader(boost::shared_ptr session, unsigned requestId, const AvatarHeader_t &avatarHeader); void HandleNetPacketUnknownAvatar(boost::shared_ptr session, unsigned requestId, const UnknownAvatar_t &unknownAvatar); void HandleNetPacketAvatarFile(boost::shared_ptr session, unsigned requestId, const AvatarData_t &avatarData); void HandleNetPacketAvatarEnd(boost::shared_ptr session, unsigned requestId, const AvatarEnd_t &avatarEnd); void HandleNetPacketRetrievePlayerInfo(boost::shared_ptr session, const PlayerInfoRequestMessage_t &playerInfoRequest); void HandleNetPacketRetrieveAvatar(boost::shared_ptr session, const AvatarRequestMessage_t &retrieveAvatar); void HandleNetPacketCreateGame(boost::shared_ptr session, bool autoLeave, const JoinNewGame_t &newGame); void HandleNetPacketJoinGame(boost::shared_ptr session, bool autoLeave, const JoinExistingGame_t &joinGame); void HandleNetPacketRejoinGame(boost::shared_ptr session, bool autoLeave, const RejoinExistingGame_t &rejoinGame); void HandleNetPacketChatRequest(boost::shared_ptr session, const ChatRequestMessage_t &chatRequest); void HandleNetPacketRejectGameInvitation(boost::shared_ptr session, const RejectGameInvitationMessage_t &reject); void HandleNetPacketReportGame(boost::shared_ptr session, const ReportGameMessage_t &report); // TODO would be better to use state pattern here. void AuthChallenge(boost::shared_ptr session, const std::string &secret); void CheckAvatarBlacklist(boost::shared_ptr session); void AvatarBlacklisted(unsigned playerId); void AvatarOK(unsigned playerId); void InitAfterLogin(boost::shared_ptr session); void EstablishSession(boost::shared_ptr session); void AuthenticatePlayer(boost::shared_ptr session); void UserValid(unsigned playerId, const DBPlayerData &dbPlayerData); void UserInvalid(unsigned playerId); void UserBlocked(unsigned playerId); void SendReportAvatarResult(unsigned byPlayerId, unsigned reportedPlayerId, bool success); void RequestPlayerAvatar(boost::shared_ptr session); void TimerRemoveGame(const boost::system::error_code &ec); void TimerRemovePlayer(const boost::system::error_code &ec); void TimerUpdateClientLoginLock(const boost::system::error_code &ec); void TimerCleanupAvatarCache(const boost::system::error_code &ec); bool IsGameNameInUse(const std::string &gameName) const; boost::shared_ptr InternalGetGameFromId(unsigned gameId); void InternalAddGame(boost::shared_ptr game); void InternalRemoveGame(boost::shared_ptr game); void InternalRemovePlayer(unsigned playerId, unsigned errorCode); void InternalMutePlayerInGame(unsigned playerId); void InternalResubscribeMsg(boost::shared_ptr session); void HandleReAddedSession(boost::shared_ptr session); void SessionTimeoutWarning(boost::shared_ptr session, unsigned remainingSec); void CleanupSessionMap(); void CloseSession(boost::shared_ptr session); void SendError(boost::shared_ptr s, int errorCode); void SendJoinGameFailed(boost::shared_ptr s, unsigned gameId, int reason); void SendPlayerList(boost::shared_ptr s); void SendGameList(boost::shared_ptr s); void UpdateStatisticsNumberOfPlayers(); void BroadcastStatisticsUpdate(const ServerStats &stats); void ReadStatisticsFile(); void TimerSaveStatisticsFile(const boost::system::error_code &ec); InternalServerCallback &GetSenderCallback(); GuiInterface &GetGui(); ServerIrcBotCallback &GetIrcBotCallback(); unsigned GetPlayerId(const std::string &name) const; static boost::shared_ptr CreateNetPacketPlayerListNew(unsigned playerId); static boost::shared_ptr CreateNetPacketPlayerListLeft(unsigned playerId); static boost::shared_ptr CreateNetPacketGameListNew(const ServerGame &game); static boost::shared_ptr CreateNetPacketGameListUpdate(unsigned gameId, GameMode mode); u_int32_t GetRejoinGameIdForPlayer(const std::string &playerName, const std::string &guid, unsigned &outPlayerUniqueId); private: boost::shared_ptr m_ioService; boost::shared_ptr m_internalServerCallback; boost::shared_ptr m_sender; SessionManager m_sessionManager; SessionManager m_gameSessionManager; Gsasl *m_authContext; TimerClientAddressMap m_timerClientAddressMap; mutable boost::mutex m_timerClientAddressMapMutex; RemoveGameList m_removeGameList; mutable boost::mutex m_removeGameListMutex; PlayerDataMap m_computerPlayers; mutable boost::mutex m_computerPlayersMutex; GameMap m_gameMap; GuiInterface &m_gui; ServerIrcBotCallback &m_ircBotCb; AvatarManager &m_avatarManager; const ServerMode m_mode; std::string m_statisticsFileName; ConfigFile &m_serverConfig; u_int32_t m_curGameId; u_int32_t m_curUniquePlayerId; u_int32_t m_curSessionId; mutable boost::mutex m_curUniquePlayerIdMutex; ServerStats m_statData; bool m_statDataChanged; mutable boost::mutex m_statMutex; boost::shared_ptr m_banManager; boost::shared_ptr m_chatCleanerManager; boost::shared_ptr m_database; boost::asio::deadline_timer m_removeGameTimer; boost::asio::deadline_timer m_saveStatisticsTimer; boost::asio::deadline_timer m_loginLockTimer; boost::uuids::random_generator m_sessionIdGenerator; const boost::posix_time::ptime m_startTime; friend class InternalServerCallback; }; #endif