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 struct LobbyPlayer 41 { 42 irr::core::stringw m_user_name; 43 int m_local_player_id; 44 uint32_t m_host_id; 45 KartTeam m_kart_team; 46 HandicapLevel m_handicap; 47 uint32_t m_online_id; 48 /* Icon used in networking lobby, see NetworkingLobby::loadedFromFile. */ 49 int m_icon_id; 50 std::string m_country_code; 51 /* Icon id for spectator in NetworkingLobby::loadedFromFile is 5. */ isSpectatorLobbyPlayer52 bool isSpectator() const { return m_icon_id == 5; } isAILobbyPlayer53 bool isAI() const { return m_icon_id == 6; } 54 }; 55 56 class ClientLobby : public LobbyProtocol 57 { 58 private: 59 void disconnectedPlayer(Event* event); 60 void connectionAccepted(Event* event); //!< Callback function on connection acceptation 61 void connectionRefused(Event* event); //!< Callback function on connection refusal 62 void startGame(Event* event); 63 void startSelection(Event* event); 64 void raceFinished(Event* event); 65 void backToLobby(Event *event); 66 // race votes 67 void receivePlayerVote(Event* event); 68 void updatePlayerList(Event* event); 69 void handleChat(Event* event); 70 void handleServerInfo(Event* event); 71 void reportSuccess(Event* event); 72 void handleBadTeam(); 73 void handleBadConnection(); 74 void becomingServerOwner(); 75 76 std::shared_ptr<Server> m_server; 77 78 enum ClientState : unsigned int 79 { 80 NONE, 81 LINKED, 82 REQUESTING_CONNECTION, 83 CONNECTED, // means in the lobby room 84 SELECTING_ASSETS, // in the kart selection or tracks screen 85 RACING, // racing 86 RACE_FINISHED, // race result shown 87 DONE, 88 EXITING 89 }; 90 91 bool m_waiting_for_game; 92 93 bool m_server_auto_game_time; 94 95 bool m_received_server_result; 96 97 bool m_auto_started; 98 99 bool m_first_connect; 100 101 bool m_spectator; 102 103 bool m_server_live_joinable; 104 105 bool m_server_send_live_load_world; 106 107 bool m_server_enabled_chat; 108 109 bool m_server_enabled_track_voting; 110 111 bool m_server_enabled_report_player; 112 113 uint64_t m_auto_back_to_lobby_time; 114 115 uint64_t m_start_live_game_time; 116 117 /** The state of the finite state machine. */ 118 std::atomic<ClientState> m_state; 119 120 std::set<std::string> m_available_karts; 121 std::set<std::string> m_available_tracks; 122 123 void addAllPlayers(Event* event); 124 void finalizeConnectionRequest(NetworkString* header, 125 BareNetworkString* rest, bool encrypt); 126 127 std::map<PeerDisconnectInfo, irr::core::stringw> m_disconnected_msg; 128 129 std::vector<LobbyPlayer> m_lobby_players; 130 131 std::vector<float> m_ranking_changes; 132 133 irr::core::stringw m_total_players; 134 135 void liveJoinAcknowledged(Event* event); 136 void handleKartInfo(Event* event); 137 void finishLiveJoin(); 138 std::vector<std::shared_ptr<NetworkPlayerProfile> > 139 decodePlayers(const BareNetworkString& data, 140 std::shared_ptr<STKPeer> peer = nullptr, 141 bool* is_spectator = NULL) const; 142 void getKartsTracksNetworkString(BareNetworkString* ns); 143 public: 144 ClientLobby(std::shared_ptr<Server> s); 145 virtual ~ClientLobby(); 146 void doneWithResults(); receivedServerResult()147 bool receivedServerResult() { return m_received_server_result; } 148 void startingRaceNow(); getAvailableKarts() const149 const std::set<std::string>& getAvailableKarts() const 150 { return m_available_karts; } getAvailableTracks() const151 const std::set<std::string>& getAvailableTracks() const 152 { return m_available_tracks; } 153 virtual bool notifyEvent(Event* event) OVERRIDE; 154 virtual bool notifyEventAsynchronous(Event* event) OVERRIDE; 155 virtual void finishedLoadingWorld() OVERRIDE; 156 virtual void setup() OVERRIDE; 157 virtual void update(int ticks) OVERRIDE; asynchronousUpdate()158 virtual void asynchronousUpdate() OVERRIDE {} allPlayersReady() const159 virtual bool allPlayersReady() const OVERRIDE 160 { return m_state.load() >= RACING; } waitingForServerRespond() const161 bool waitingForServerRespond() const 162 { return m_state.load() == REQUESTING_CONNECTION; } isLobbyReady() const163 bool isLobbyReady() const { return !m_first_connect; } isWaitingForGame() const164 bool isWaitingForGame() const { return m_waiting_for_game; } isServerAutoGameTime() const165 bool isServerAutoGameTime() const { return m_server_auto_game_time; } isRacing() const166 virtual bool isRacing() const OVERRIDE { return m_state.load() == RACING; } 167 void requestKartInfo(uint8_t kart_id); setSpectator(bool val)168 void setSpectator(bool val) { m_spectator = val; } isSpectator() const169 bool isSpectator() const 170 { return m_spectator && m_state.load() != RACE_FINISHED; } 171 void startLiveJoinKartSelection(); 172 void sendChat(irr::core::stringw text, KartTeam team); getLobbyPlayers() const173 const std::vector<LobbyPlayer>& getLobbyPlayers() const 174 { return m_lobby_players; } isServerLiveJoinable() const175 bool isServerLiveJoinable() const { return m_server_live_joinable; } 176 void changeSpectateTarget(PlayerAction action, int value, 177 Input::InputType type) const; 178 void addSpectateHelperMessage() const; serverEnabledChat() const179 bool serverEnabledChat() const { return m_server_enabled_chat; } serverEnabledTrackVoting() const180 bool serverEnabledTrackVoting() const 181 { return m_server_enabled_track_voting; } serverEnabledReportPlayer() const182 bool serverEnabledReportPlayer() const 183 { return m_server_enabled_report_player; } getRankingChanges() const184 const std::vector<float>& getRankingChanges() const 185 { return m_ranking_changes; } 186 void handleClientCommand(const std::string& cmd); 187 void updateAssetsToServer(); getCurrentState() const188 ClientState getCurrentState() const { return m_state.load(); } getJoinedServer() const189 std::shared_ptr<Server> getJoinedServer() const { return m_server; } 190 }; 191 192 #endif // CLIENT_LOBBY_HPP 193