SuperTuxKart
client_lobby.hpp
1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2018 SuperTuxKart-Team
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 3
8 // of the 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 General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #ifndef CLIENT_LOBBY_HPP
20 #define CLIENT_LOBBY_HPP
21 
22 #include "input/input.hpp"
23 #include "network/protocols/lobby_protocol.hpp"
24 #include "utils/cpp2011.hpp"
25 
26 #include <enet/enet.h>
27 
28 #include <atomic>
29 #include <map>
30 #include <memory>
31 #include <set>
32 
33 enum PeerDisconnectInfo : unsigned int;
34 enum KartTeam : int8_t;
35 enum HandicapLevel : uint8_t;
36 
37 class BareNetworkString;
38 class Server;
39 
40 namespace Online
41 {
42  class HTTPRequest;
43 }
44 
46 {
47  irr::core::stringw m_user_name;
48  int m_local_player_id;
49  uint32_t m_host_id;
50  KartTeam m_kart_team;
51  HandicapLevel m_handicap;
52  uint32_t m_online_id;
53  /* Icon used in networking lobby, see NetworkingLobby::loadedFromFile. */
54  int m_icon_id;
55  std::string m_country_code;
56  /* Icon id for spectator in NetworkingLobby::loadedFromFile is 5. */
57  bool isSpectator() const { return m_icon_id == 5; }
58  bool isAI() const { return m_icon_id == 6; }
59 };
60 
61 class ClientLobby : public LobbyProtocol
62 {
63 private:
64  void disconnectedPlayer(Event* event);
65  void connectionAccepted(Event* event);
66  void connectionRefused(Event* event);
67  void startGame(Event* event);
68  void startSelection(Event* event);
69  void raceFinished(Event* event);
70  void backToLobby(Event *event);
71  // race votes
72  void receivePlayerVote(Event* event);
73  void updatePlayerList(Event* event);
74  void handleChat(Event* event);
75  void handleServerInfo(Event* event);
76  void reportSuccess(Event* event);
77  void handleBadTeam();
78  void handleBadConnection();
79  void becomingServerOwner();
80 
81  std::shared_ptr<Server> m_server;
82 
83  enum ClientState : unsigned int
84  {
85  NONE,
86  LINKED,
87  REQUESTING_CONNECTION,
88  CONNECTED, // means in the lobby room
89  SELECTING_ASSETS, // in the kart selection or tracks screen
90  RACING, // racing
91  RACE_FINISHED, // race result shown
92  DONE,
93  EXITING
94  };
95 
96  bool m_waiting_for_game;
97 
98  bool m_server_auto_game_time;
99 
100  bool m_received_server_result;
101 
102  bool m_auto_started;
103 
104  bool m_first_connect;
105 
106  bool m_spectator;
107 
108  bool m_server_live_joinable;
109 
110  bool m_server_send_live_load_world;
111 
112  bool m_server_enabled_chat;
113 
114  bool m_server_enabled_track_voting;
115 
116  bool m_server_enabled_report_player;
117 
118  uint64_t m_auto_back_to_lobby_time;
119 
120  uint64_t m_start_live_game_time;
121 
123  std::atomic<ClientState> m_state;
124 
125  std::set<std::string> m_available_karts;
126  std::set<std::string> m_available_tracks;
127 
128  void addAllPlayers(Event* event);
129  void finalizeConnectionRequest(NetworkString* header,
130  BareNetworkString* rest, bool encrypt);
131 
132  std::map<PeerDisconnectInfo, irr::core::stringw> m_disconnected_msg;
133 
134  std::vector<LobbyPlayer> m_lobby_players;
135 
136  std::vector<float> m_ranking_changes;
137 
138  irr::core::stringw m_total_players;
139 
140  static std::thread m_background_download;
141 
142  static std::shared_ptr<Online::HTTPRequest> m_download_request;
143 
144  void liveJoinAcknowledged(Event* event);
145  void handleKartInfo(Event* event);
146  void finishLiveJoin();
147  std::vector<std::shared_ptr<NetworkPlayerProfile> >
148  decodePlayers(const BareNetworkString& data,
149  std::shared_ptr<STKPeer> peer = nullptr,
150  bool* is_spectator = NULL) const;
151  void getPlayersAddonKartType(const BareNetworkString& data,
152  std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
153  void getKartsTracksNetworkString(BareNetworkString* ns);
154  void doInstallAddonsPack();
155 public:
156  ClientLobby(std::shared_ptr<Server> s);
157  virtual ~ClientLobby();
158  void doneWithResults();
159  bool receivedServerResult() { return m_received_server_result; }
160  void startingRaceNow();
161  const std::set<std::string>& getAvailableKarts() const
162  { return m_available_karts; }
163  const std::set<std::string>& getAvailableTracks() const
164  { return m_available_tracks; }
165  virtual bool notifyEvent(Event* event) OVERRIDE;
166  virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
167  virtual void finishedLoadingWorld() OVERRIDE;
168  virtual void setup() OVERRIDE;
169  virtual void update(int ticks) OVERRIDE;
170  virtual void asynchronousUpdate() OVERRIDE {}
171  virtual bool allPlayersReady() const OVERRIDE
172  { return m_state.load() >= RACING; }
173  bool waitingForServerRespond() const
174  { return m_state.load() == REQUESTING_CONNECTION; }
175  bool isLobbyReady() const { return !m_first_connect; }
176  bool isWaitingForGame() const { return m_waiting_for_game; }
177  bool isServerAutoGameTime() const { return m_server_auto_game_time; }
178  virtual bool isRacing() const OVERRIDE { return m_state.load() == RACING; }
179  void requestKartInfo(uint8_t kart_id);
180  void setSpectator(bool val) { m_spectator = val; }
181  bool isSpectator() const
182  { return m_spectator && m_state.load() != RACE_FINISHED; }
183  void startLiveJoinKartSelection();
184  void sendChat(irr::core::stringw text, KartTeam team);
185  const std::vector<LobbyPlayer>& getLobbyPlayers() const
186  { return m_lobby_players; }
187  bool isServerLiveJoinable() const { return m_server_live_joinable; }
188  void changeSpectateTarget(PlayerAction action, int value,
189  Input::InputType type) const;
190  void addSpectateHelperMessage() const;
191  bool serverEnabledChat() const { return m_server_enabled_chat; }
192  bool serverEnabledTrackVoting() const
193  { return m_server_enabled_track_voting; }
194  bool serverEnabledReportPlayer() const
195  { return m_server_enabled_report_player; }
196  const std::vector<float>& getRankingChanges() const
197  { return m_ranking_changes; }
198  void handleClientCommand(const std::string& cmd);
199  ClientState getCurrentState() const { return m_state.load(); }
200  std::shared_ptr<Server> getJoinedServer() const { return m_server; }
201  static bool startedDownloadAddonsPack()
202  { return m_background_download.joinable() || m_download_request; }
203  static void downloadAddonsPack(std::shared_ptr<Online::HTTPRequest> r);
204  static void destroyBackgroundDownload();
205  void updateAssetsToServer();
206 };
207 
208 #endif // CLIENT_LOBBY_HPP
Describes a chain of 8-bit unsigned integers.
Definition: network_string.hpp:53
Definition: client_lobby.hpp:62
void doInstallAddonsPack()
Called when the asynchronous download of the addon finished.
Definition: client_lobby.cpp:1940
void raceFinished(Event *event)
Called when all karts have finished the race.
Definition: client_lobby.cpp:1146
void disconnectedPlayer(Event *event)
Called when a new player is disconnected.
Definition: client_lobby.cpp:626
std::atomic< ClientState > m_state
The state of the finite state machine.
Definition: client_lobby.hpp:123
void startSelection(Event *event)
Called when the kart selection starts.
Definition: client_lobby.cpp:1063
virtual void asynchronousUpdate() OVERRIDE
Called by the protocol listener as often as possible.
Definition: client_lobby.hpp:170
virtual void setup() OVERRIDE
A previous GameSetup is deleted and a new one is created.
Definition: client_lobby.cpp:158
void connectionRefused(Event *event)
Callback function on connection refusal.
Definition: client_lobby.cpp:967
virtual void update(int ticks) OVERRIDE
Called by the protocol listener, synchronously with the main loop.
Definition: client_lobby.cpp:405
virtual bool notifyEvent(Event *event) OVERRIDE
Notify a protocol matching the Event type of that event.
Definition: client_lobby.cpp:188
void doneWithResults()
Called from the gui when a client clicked on 'continue' on the race result screen.
Definition: client_lobby.cpp:178
void backToLobby(Event *event)
Called when the server informs the clients to exit the race result screen.
Definition: client_lobby.cpp:1216
virtual bool notifyEventAsynchronous(Event *event) OVERRIDE
Notify a protocol matching the Event type of that event.
Definition: client_lobby.cpp:226
ClientLobby(std::shared_ptr< Server > s)
The protocol that manages starting a race with the server.
Definition: client_lobby.cpp:121
void startGame(Event *event)
Called when the server broadcasts to start the race to all clients.
Definition: client_lobby.cpp:1019
void connectionAccepted(Event *event)
Callback function on connection acceptation.
Definition: client_lobby.cpp:665
virtual void finishedLoadingWorld() OVERRIDE
Callback when the world is loaded.
Definition: client_lobby.cpp:1289
Class representing an event that need to pass trough the system. This is used to remove ENet dependen...
Definition: event.hpp:73
Base class for both client and server lobby. The lobbies are started when a server opens a game,...
Definition: lobby_protocol.hpp:47
A new implementation of NetworkString, which has a fixed format: Byte 0: The type of the message,...
Definition: network_string.hpp:422
Definition: server.hpp:44
PlayerAction
types of input events / what actions the players can do
Definition: input.hpp:117
HandicapLevel
Handicap per player.
Definition: remote_kart_info.hpp:43
PeerDisconnectInfo
Definition: stk_peer.hpp:48
Definition: client_lobby.hpp:46