1 /*
2  * Copyright (C) 2008-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_NETWORK_GAMEHOST_H
21 #define WL_NETWORK_GAMEHOST_H
22 
23 #include <memory>
24 
25 #include "logic/game_controller.h"
26 #include "logic/game_settings.h"
27 #include "logic/player_end_result.h"
28 #include "network/nethost_interface.h"
29 #include "network/network.h"
30 
31 struct ChatMessage;
32 struct GameHostImpl;
33 struct Client;
34 
35 /**
36  * GameHost manages the lifetime of a network game in which this computer
37  * acts as the host.
38  *
39  * This includes running the game setup screen and the actual game after
40  * launch, as well as dealing with the actual network protocol.
41  */
42 struct GameHost : public GameController {
43 	/** playernumber 0 identifies the spectators */
44 	static constexpr uint8_t kSpectatorPlayerNum = 0;
45 
46 	GameHost(const std::string& playername, bool internet = false);
47 	~GameHost() override;
48 
49 	void run();
50 	const std::string& get_local_playername() const;
51 	int16_t get_local_playerposition();
52 
53 	// GameController interface
54 	void think() override;
55 	void send_player_command(Widelands::PlayerCommand*) override;
56 	int32_t get_frametime() override;
57 	GameController::GameType get_game_type() override;
58 
59 	uint32_t real_speed() override;
60 	uint32_t desired_speed() override;
61 	void set_desired_speed(uint32_t speed) override;
62 	bool is_paused() override;
63 	void set_paused(bool paused) override;
64 	// End GameController interface
65 
66 	// Pregame-related stuff
67 	const GameSettings& settings() const;
68 	/** return true in case all conditions for the game start are met */
69 	bool can_launch();
70 	void set_scenario(bool);
71 	void set_map(const std::string& mapname,
72 	             const std::string& mapfilename,
73 	             uint32_t maxplayers,
74 	             bool savegame = false);
75 	void set_player_state(uint8_t number, PlayerSettings::State state, bool host = false);
76 	void set_player_tribe(uint8_t number, const std::string& tribe, bool const random_tribe = false);
77 	void set_player_init(uint8_t number, uint8_t index);
78 	void set_player_ai(uint8_t number, const std::string& name, bool const random_ai = false);
79 	void set_player_name(uint8_t number, const std::string& name);
80 	void set_player(uint8_t number, const PlayerSettings&);
81 	void set_player_number(uint8_t number);
82 	void set_player_team(uint8_t number, Widelands::TeamNumber team);
83 	void set_player_closeable(uint8_t number, bool closeable);
84 	void set_player_shared(PlayerSlot number, Widelands::PlayerNumber shared);
85 	void switch_to_player(uint32_t user, uint8_t number);
86 	void set_win_condition_script(const std::string& wc);
87 	void set_peaceful_mode(bool peace);
88 	void replace_client_with_ai(uint8_t playernumber, const std::string& ai);
89 
90 	// just visible stuff for the select mapmenu
91 	void set_multiplayer_game_settings();
92 
93 	// Chat-related stuff
94 	void send(ChatMessage msg);
95 
96 	//  Host command related stuff
97 	int32_t check_client(const std::string& name);
98 	void kick_user(uint32_t, const std::string&);
99 	void split_command_array(const std::string& cmdarray,
100 	                         std::string& cmd,
101 	                         std::string& arg1,
102 	                         std::string& arg2);
103 
104 	void report_result(uint8_t player,
105 	                   Widelands::PlayerEndResult result,
106 	                   const std::string& info) override;
107 
force_pauseGameHost108 	void force_pause() {
109 		forced_pause_ = true;
110 		update_network_speed();
111 	}
112 
end_forced_pauseGameHost113 	void end_forced_pause() {
114 		forced_pause_ = false;
115 		update_network_speed();
116 	}
117 
forced_pauseGameHost118 	bool forced_pause() {
119 		return forced_pause_;
120 	}
121 
122 private:
123 	void send_system_message_code(const std::string&,
124 	                              const std::string& a = "",
125 	                              const std::string& b = "",
126 	                              const std::string& c = "");
127 	void request_sync_reports();
128 	void check_sync_reports();
129 	void sync_report_callback();
130 
131 	void clear_computer_players();
132 	void init_computer_player(Widelands::PlayerNumber p);
133 	void init_computer_players();
134 
135 	void handle_disconnect(uint32_t client_num, RecvPacket& r);
136 	void handle_ping(Client& client);
137 	void handle_hello(uint32_t client_num, uint8_t cmd, Client& client, RecvPacket& r);
138 	void handle_changetribe(Client& client, RecvPacket& r);
139 	void handle_changeshared(Client& client, RecvPacket& r);
140 	void handle_changeteam(Client& client, RecvPacket& r);
141 	void handle_changeinit(Client& client, RecvPacket& r);
142 	void handle_changeposition(Client& client, RecvPacket& r);
143 	void handle_nettime(uint32_t client_num, RecvPacket& r);
144 	void handle_playercommmand(uint32_t client_num, Client& client, RecvPacket& r);
145 	void handle_syncreport(uint32_t client_num, Client& client, RecvPacket& r);
146 	void handle_chat(Client& client, RecvPacket& r);
147 	void handle_speed(Client& client, RecvPacket& r);
148 	void handle_new_file(Client& client);
149 	void handle_file_part(Client& client, RecvPacket& r);
150 
151 	void handle_packet(uint32_t i, RecvPacket&);
152 	void handle_network();
153 	void send_file_part(NetHostInterface::ConnectionId client_sock_id, uint32_t part);
154 
155 	void check_hung_clients();
156 	void broadcast_real_speed(uint32_t speed);
157 	void update_network_speed();
158 
159 	std::string get_computer_player_name(uint8_t playernum);
160 	bool has_user_name(const std::string& name, uint8_t ignoreplayer = UserSettings::none());
161 	void welcome_client(uint32_t number, std::string& playername);
162 	void committed_network_time(int32_t time);
163 	void receive_client_time(uint32_t number, int32_t time);
164 
165 	void broadcast(SendPacket&);
166 	void write_setting_map(SendPacket&);
167 	void write_setting_player(SendPacket&, uint8_t number);
168 	void broadcast_setting_player(uint8_t number);
169 	void write_setting_all_players(SendPacket&);
170 	void write_setting_user(SendPacket& packet, uint32_t number);
171 	void broadcast_setting_user(uint32_t number);
172 	void write_setting_all_users(SendPacket&);
173 	bool write_map_transfer_info(SendPacket&, std::string);
174 
175 	void disconnect_player_controller(uint8_t number, const std::string& name);
176 	void disconnect_client(uint32_t number,
177 	                       const std::string& reason,
178 	                       bool sendreason = true,
179 	                       const std::string& arg = "");
180 	void reaper();
181 
182 	std::unique_ptr<NetTransferFile> file_;
183 	GameHostImpl* d;
184 	bool internet_;
185 	bool forced_pause_;  // triggered by the forcePause host chat command, see HostChatProvider in
186 	                     // gamehost.cc
187 };
188 
189 #endif  // end of include guard: WL_NETWORK_GAMEHOST_H
190