1 /*****************************************************************************
2  * PokerTH - The open source texas holdem engine                             *
3  * Copyright (C) 2006-2012 Felix Hammer, Florian Thauer, Lothar May          *
4  *                                                                           *
5  * This program is free software: you can redistribute it and/or modify      *
6  * it under the terms of the GNU Affero General Public License as            *
7  * published by the Free Software Foundation, either version 3 of the        *
8  * License, or (at your option) any later version.                           *
9  *                                                                           *
10  * This program is distributed in the hope that it will be useful,           *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
13  * GNU Affero General Public License for more details.                       *
14  *                                                                           *
15  * You should have received a copy of the GNU Affero General Public License  *
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.     *
17  *                                                                           *
18  *                                                                           *
19  * Additional permission under GNU AGPL version 3 section 7                  *
20  *                                                                           *
21  * If you modify this program, or any covered work, by linking or            *
22  * combining it with the OpenSSL project's OpenSSL library (or a             *
23  * modified version of that library), containing parts covered by the        *
24  * terms of the OpenSSL or SSLeay licenses, the authors of PokerTH           *
25  * (Felix Hammer, Florian Thauer, Lothar May) grant you additional           *
26  * permission to convey the resulting work.                                  *
27  * Corresponding Source for a non-source form of such a combination          *
28  * shall include the source code for the parts of OpenSSL used as well       *
29  * as that of the covered work.                                              *
30  *****************************************************************************/
31 /* Network server game. */
32 
33 #ifndef _SERVERGAME_H_
34 #define _SERVERGAME_H_
35 
36 #include <boost/enable_shared_from_this.hpp>
37 #include <boost/asio/steady_timer.hpp>
38 #include <third_party/boost/timers.hpp>
39 #include <map>
40 
41 #include <net/sessionmanager.h>
42 #include <db/serverdbcallback.h>
43 #include <gui/guiinterface.h>
44 #include <gamedata.h>
45 
46 
47 class ServerLobbyThread;
48 class ServerGameState;
49 class ServerDBInterface;
50 class PlayerInterface;
51 class ConfigFile;
52 struct GameData;
53 class Game;
54 
55 class ServerGame : public boost::enable_shared_from_this<ServerGame>
56 {
57 public:
58 	ServerGame(
59 		boost::shared_ptr<ServerLobbyThread> lobbyThread, u_int32_t id, const std::string &name, const std::string &pwd, const GameData &gameData,
60 		unsigned adminPlayerId, unsigned creatorPlayerDBId, GuiInterface &gui, ConfigFile &playerConfig);
61 	virtual ~ServerGame();
62 
63 	void Init();
64 	void Exit();
65 
66 	u_int32_t GetId() const;
67 	const std::string &GetName() const;
68 	unsigned GetCreatorDBId() const;
69 
70 	void AddSession(boost::shared_ptr<SessionData> session, bool spectateOnly);
71 	void RemovePlayer(unsigned playerId, unsigned errorCode);
72 	void MutePlayer(unsigned playerId, bool mute);
73 	void MarkPlayerAsInactive(unsigned playerId);
74 	void MarkPlayerAsKicked(unsigned playerId);
75 
76 	void HandlePacket(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet);
77 
78 	ServerCallback &GetCallback();
79 	GameState GetCurRound() const;
80 
81 	void SendToAllPlayers(boost::shared_ptr<NetPacket> packet, int state);
82 	void SendToAllButOnePlayers(boost::shared_ptr<NetPacket> packet, SessionId except, int state);
83 	void RemoveAllSessions();
84 	void MoveSpectatorsToLobby();
85 
86 	bool IsPasswordProtected() const;
87 	bool CheckPassword(const std::string &password) const;
88 	static bool CheckSettings(const GameData &data, const std::string &password, ServerMode mode);
89 	const GameData &GetGameData() const;
90 
91 	boost::shared_ptr<PlayerData> GetPlayerDataByUniqueId(unsigned playerId) const;
92 	PlayerIdList GetPlayerIdList() const;
93 	PlayerIdList GetSpectatorIdList() const;
94 	bool IsPlayerConnected(const std::string &name) const;
95 	bool IsPlayerConnected(unsigned playerId) const;
96 	bool IsClientAddressConnected(const std::string &clientAddress) const;
97 	boost::shared_ptr<PlayerInterface> GetPlayerInterfaceFromGame(const std::string &playerName);
98 	boost::shared_ptr<PlayerInterface> GetPlayerInterfaceFromGame(unsigned playerId);
99 
100 	bool IsRunning() const;
101 
102 	unsigned GetAdminPlayerId() const;
103 	void SetAdminPlayerId(unsigned playerId);
104 
105 	void AddPlayerInvitation(unsigned playerId);
106 	void RemovePlayerInvitation(unsigned playerId);
107 	bool IsPlayerInvited(unsigned playerId) const;
108 
109 	void SetPlayerAutoLeaveOnFinish(unsigned playerId);
110 
111 	void AddRejoinPlayer(unsigned playerId);
112 	PlayerIdList GetAndResetRejoinPlayers();
113 
114 	void AddReactivatePlayer(unsigned playerId);
115 	PlayerIdList GetAndResetReactivatePlayers();
116 
117 	void AddNewSpectator(unsigned playerId);
118 	PlayerIdList GetAndResetNewSpectators();
119 
120 	void SetNameReported();
121 	bool IsNameReported() const;
122 
123 	// should be protected, but is needed in function.
124 	const Game &GetGame() const;
125 	Game &GetGame();
126 
127 	void KickPlayer(unsigned playerId);
128 
129 	void AddPlayerToNumJoinsPerPlayer(const std::string &playerName);
130 	int GetNumJoinsPerPlayer(const std::string &playerName);
131 
132 protected:
133 
134 	struct RankingData {
RankingDataRankingData135 		RankingData() : dbid(DB_ID_INVALID), place(0) {}
dbidRankingData136 		RankingData(DB_id i, int p = 0) : dbid(i), place(p) {}
137 		DB_id dbid;
138 		int place;
139 	};
140 
141 	typedef std::map<unsigned, RankingData> RankingMap;
142 
143 	void TimerVoteKick(const boost::system::error_code &ec);
144 
145 	PlayerDataList InternalStartGame();
146 	void InitRankingMap(const PlayerDataList &playerDataList);
147 	void UpdateRankingMap();
148 	void SetPlayerPlace(unsigned playerId, int place);
149 	void ReplaceRankingPlayer(unsigned oldPlayerId, unsigned newPlayerId);
150 	void StoreAndResetRanking();
151 	void RemoveAutoLeavePlayers();
152 	void InternalEndGame();
153 
154 	void InternalAskVoteKick(boost::shared_ptr<SessionData> byWhom, unsigned playerIdWho, unsigned timeoutSec);
155 	void InternalDenyAskVoteKick(boost::shared_ptr<SessionData> byWhom, unsigned playerIdWho, DenyKickPlayerReason reason);
156 	void InternalVoteKick(boost::shared_ptr<SessionData> byWhom, unsigned petitionId, KickVote vote);
157 	void InternalDenyVoteKick(boost::shared_ptr<SessionData> byWhom, unsigned petitionId, DenyVoteReason reason);
158 
159 	PlayerDataList GetFullPlayerDataList() const;
160 
161 	void AddComputerPlayer(boost::shared_ptr<PlayerData> player);
162 	boost::shared_ptr<PlayerData> RemoveComputerPlayer(unsigned playerId);
163 	bool IsComputerPlayerActive(unsigned playerId) const;
164 	void ResetComputerPlayerList();
165 
166 	void RemoveSession(boost::shared_ptr<SessionData> session, int reason);
167 	void RemovePlayerData(boost::shared_ptr<PlayerData> player, int reason, bool spectateOnly);
168 	void SessionError(boost::shared_ptr<SessionData> session, int errorCode);
169 	void MoveSessionToLobby(boost::shared_ptr<SessionData> session, int reason);
170 
171 	void RemoveDisconnectedPlayers();
172 	int GetCurNumberOfPlayers() const;
173 	void AssignPlayerNumbers(PlayerDataList &playerList);
174 	bool IsValidPlayer(unsigned playerId) const;
175 
176 	void AddReportedAvatar(unsigned playerId);
177 	bool IsAvatarReported(unsigned playerId) const;
178 
179 	ServerLobbyThread &GetLobbyThread();
180 
181 	ServerGameState &GetState();
182 	void SetState(ServerGameState &newState);
183 
184 	boost::asio::steady_timer &GetStateTimer1();
185 	boost::asio::steady_timer &GetStateTimer2();
186 
187 	const StartData &GetStartData() const;
188 	void SetStartData(const StartData &startData);
189 
190 	GuiInterface &GetGui();
191 
192 	unsigned GetNextGameNum();
193 
194 	const SessionManager &GetSessionManager() const;
195 	SessionManager &GetSessionManager();
196 	ServerDBInterface &GetDatabase();
197 
198 	typedef std::map<std::string, int> NumJoinsPerPlayerMap;
199 
200 private:
201 	ServerGame(const ServerGame &other);
202 
203 	SessionManager m_sessionManager;
204 	PlayerDataList m_computerPlayerList;
205 	mutable boost::mutex m_computerPlayerListMutex;
206 
207 	PlayerIdList m_playerInvitationList;
208 	mutable boost::mutex m_playerInvitationListMutex;
209 
210 	PlayerIdList m_autoLeavePlayerList;
211 	mutable boost::mutex m_autoLeavePlayerListMutex;
212 
213 	PlayerIdList m_rejoinPlayerList;
214 	mutable boost::mutex m_rejoinPlayerListMutex;
215 
216 	PlayerIdList m_reactivatePlayerList;
217 	mutable boost::mutex m_reactivatePlayerListMutex;
218 
219 	PlayerIdList m_newSpectatorList;
220 	mutable boost::mutex m_newSpectatorListMutex;
221 
222 	PlayerIdList m_reportedAvatarList;
223 
224 	RankingMap m_rankingMap;
225 
226 	unsigned m_adminPlayerId;
227 
228 	boost::shared_ptr<VoteKickData> m_voteKickData;
229 
230 	boost::shared_ptr<ServerLobbyThread> m_lobbyThread;
231 	boost::shared_ptr<ServerDBInterface> m_database;
232 	GuiInterface &m_gui;
233 
234 	const GameData		m_gameData;
235 	StartData			m_startData;
236 	boost::shared_ptr<Game>	 m_game;
237 	ServerGameState			*m_curState;
238 
239 	const u_int32_t		m_id;
240 	const std::string	m_name;
241 	const std::string	m_password;
242 	const unsigned		m_creatorPlayerDBId;
243 	ConfigFile		   &m_playerConfig;
244 	unsigned			m_gameNum;
245 	unsigned			m_curPetitionId;
246 	boost::asio::steady_timer m_voteKickTimer;
247 	boost::asio::steady_timer m_stateTimer1;
248 	boost::asio::steady_timer m_stateTimer2;
249 	bool				m_isNameReported;
250 
251 	friend class ServerLobbyThread;
252 	friend class AbstractServerGameStateReceiving;
253 	friend class AbstractServerGameStateRunning;
254 	friend class ServerGameStateInit;
255 	friend class ServerGameStateWaitAck;
256 	friend class ServerGameStateStartGame;
257 	friend class ServerGameStateHand;
258 	friend class ServerGameStateWaitPlayerAction;
259 	friend class ServerGameStateWaitNextHand;
260 
261 	NumJoinsPerPlayerMap m_numJoinsPerPlayer;
262 };
263 
264 #endif
265