SuperTuxKart
Loading...
Searching...
No Matches
lobby_protocol.hpp
1//
2// SuperTuxKart - a fun racing game with go-kart
3// Copyright (C) 2013-2015 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 LOBBY_PROTOCOL_HPP
20#define LOBBY_PROTOCOL_HPP
21
22#include "network/protocol.hpp"
23#include "utils/stk_process.hpp"
24
25class GameSetup;
27class PeerVote;
28class RemoteKartInfo;
29class Track;
30
31#include <atomic>
32#include <cassert>
33#include <map>
34#include <memory>
35#include <mutex>
36#include <string>
37#include <thread>
38#include <vector>
39
46class LobbyProtocol : public Protocol
47{
48public:
50 enum : uint8_t
51 {
52 LE_CONNECTION_REQUESTED = 1, // a connection to the server
53 LE_CONNECTION_REFUSED, // Connection to server refused
54 LE_CONNECTION_ACCEPTED, // Connection to server accepted
55 LE_SERVER_INFO, // inform client about server info
56 LE_REQUEST_BEGIN, // begin of kart selection
57 LE_UPDATE_PLAYER_LIST, // inform client about player list update
58 LE_KART_SELECTION, // Player selected kart
59 LE_PLAYER_DISCONNECTED, // Client disconnected
60 LE_CLIENT_LOADED_WORLD, // Client finished loading world
61 LE_LOAD_WORLD, // Clients should load world
62 LE_START_RACE, // Server to client to start race
63 LE_START_SELECTION, // inform client to start selection
64 LE_RACE_FINISHED, // race has finished, display result
65 LE_RACE_FINISHED_ACK, // client went back to lobby
66 LE_BACK_LOBBY, // Force clients to go back to lobby
67 LE_VOTE, // Track vote
68 LE_CHAT, // Client chat message
69 LE_SERVER_OWNERSHIP, // Tell client he is now the server owner
70 LE_KICK_HOST, // Server owner kicks some other peer in game
71 LE_CHANGE_TEAM, // Client wants to change his team
72 LE_BAD_TEAM, // Tell server owner that the team is unbalanced
73 LE_BAD_CONNECTION, // High ping or too many packets loss
74 LE_CONFIG_SERVER, // Server owner config server game mode or difficulty
75 LE_CHANGE_HANDICAP, // Client changes handicap
76 LE_LIVE_JOIN, // Client live join or spectate
77 LE_LIVE_JOIN_ACK, // Server tell client live join or spectate succeed
78 LE_KART_INFO, // Client or server exchange new kart info
79 LE_CLIENT_BACK_LOBBY, // Client tell server to go back lobby
80 LE_REPORT_PLAYER, // Client report some player in server
81 // (like abusive behaviour)
82 LE_ASSETS_UPDATE, // Client tell server with updated assets
83 LE_COMMAND, // Command
84 };
85
86 enum RejectReason : uint8_t
87 {
88 RR_BUSY = 0,
89 RR_BANNED = 1,
90 RR_INCORRECT_PASSWORD = 2,
91 RR_INCOMPATIBLE_DATA = 3,
92 RR_TOO_MANY_PLAYERS = 4,
93 RR_INVALID_PLAYER = 5
94 };
95
96 enum BackLobbyReason : uint8_t
97 {
98 BLR_NONE = 0,
99 BLR_NO_GAME_FOR_LIVE_JOIN = 1,
100 BLR_NO_PLACE_FOR_LIVE_JOIN = 2,
101 BLR_ONE_PLAYER_IN_RANKED_MATCH = 3,
102 BLR_SERVER_ONWER_QUITED_THE_GAME = 4,
103 BLR_SPECTATING_NEXT_GAME = 5
104 };
105
106protected:
107 const ProcessType m_process_type;
110 std::map<uint32_t, PeerVote> m_peers_votes;
111
113 std::atomic<uint64_t> m_end_voting_period;
114
117
118 std::thread m_start_game_thread;
119
120 static std::weak_ptr<LobbyProtocol> m_lobby[PT_COUNT];
121
124 std::atomic<uint32_t> m_estimated_remaining_time;
125
128 std::atomic<uint32_t> m_estimated_progress;
129
133
135 mutable std::mutex m_current_track_mutex;
136
138 std::string m_current_track;
139
142
143 // ------------------------------------------------------------------------
144 void configRemoteKart(
145 const std::vector<std::shared_ptr<NetworkPlayerProfile> >& players,
146 int local_player_size) const;
147 // ------------------------------------------------------------------------
148 void joinStartGameThread()
149 {
150 if (m_start_game_thread.joinable())
151 m_start_game_thread.join();
152 }
153 // ------------------------------------------------------------------------
154 void addLiveJoiningKart(int kart_id, const RemoteKartInfo& rki,
155 int live_join_util_ticks) const;
156 // ------------------------------------------------------------------------
157 void exitGameState();
158public:
159
161 template<typename Singleton, typename... Types>
162 static std::shared_ptr<Singleton> create(Types ...args)
163 {
164 ProcessType pt = STKProcess::getType();
165 assert(m_lobby[pt].expired());
166 auto ret = std::make_shared<Singleton>(args...);
167 m_lobby[pt] = ret;
168 return std::dynamic_pointer_cast<Singleton>(ret);
169 } // create
170
171 // ------------------------------------------------------------------------
173 template<class T> static std::shared_ptr<T> get()
174 {
175 ProcessType pt = STKProcess::getType();
176 if (std::shared_ptr<LobbyProtocol> lp = m_lobby[pt].lock())
177 {
178 std::shared_ptr<T> new_type = std::dynamic_pointer_cast<T>(lp);
179 if (new_type)
180 return new_type;
181 }
182 return nullptr;
183 } // get
184
185 // ------------------------------------------------------------------------
187 template<class T> static std::shared_ptr<T> getByType(ProcessType pt)
188 {
189 if (std::shared_ptr<LobbyProtocol> lp = m_lobby[pt].lock())
190 {
191 std::shared_ptr<T> new_type = std::dynamic_pointer_cast<T>(lp);
192 if (new_type)
193 return new_type;
194 }
195 return nullptr;
196 } // get
197
198 // ------------------------------------------------------------------------
199
201 virtual ~LobbyProtocol();
202 virtual void setup() = 0;
203 virtual void update(int ticks) = 0;
204 virtual void finishedLoadingWorld() = 0;
205 virtual void loadWorld();
206 virtual bool allPlayersReady() const = 0;
207 virtual bool isRacing() const = 0;
208 void startVotingPeriod(float max_time);
210 bool isVotingOver();
211 // ------------------------------------------------------------------------
213 float getMaxVotingTime() { return m_max_voting_time / 1000.0f; }
214 // ------------------------------------------------------------------------
217 // ------------------------------------------------------------------------
219 int getNumberOfVotes() const { return (int)m_peers_votes.size(); }
220 // -----------------------------------------------------------------------
221 void addVote(uint32_t host_id, const PeerVote &vote);
222 // -----------------------------------------------------------------------
223 const PeerVote* getVote(uint32_t host_id) const;
224 // -----------------------------------------------------------------------
225 void resetVotingTime() { m_end_voting_period.store(0); }
226 // -----------------------------------------------------------------------
228 const std::map<uint32_t, PeerVote>& getAllVotes() const
229 { return m_peers_votes; }
230 // -----------------------------------------------------------------------
231 std::pair<uint32_t, uint32_t> getGameStartedProgress() const
232 {
233 return std::make_pair(m_estimated_remaining_time.load(),
234 m_estimated_progress.load());
235 }
236 // ------------------------------------------------------------------------
237 void setGameStartedProgress(const std::pair<uint32_t, uint32_t>& p)
238 {
239 m_estimated_remaining_time.store(p.first);
240 m_estimated_progress.store(p.second);
241 }
242 // ------------------------------------------------------------------------
243 void resetGameStartedProgress()
244 {
245 m_estimated_remaining_time.store(std::numeric_limits<uint32_t>::max());
246 m_estimated_progress.store(std::numeric_limits<uint32_t>::max());
247 }
248 // ------------------------------------------------------------------------
249 bool hasLiveJoiningRecently() const;
250 // ------------------------------------------------------------------------
251 void storePlayingTrack(const std::string& track_ident)
252 {
253 std::lock_guard<std::mutex> lock(m_current_track_mutex);
254 m_current_track = track_ident;
255 }
256 // ------------------------------------------------------------------------
257 std::string getPlayingTrackIdent() const
258 {
259 std::lock_guard<std::mutex> lock(m_current_track_mutex);
260 return m_current_track;
261 }
262 // ------------------------------------------------------------------------
263 Track* getPlayingTrack() const;
264}; // class LobbyProtocol
265
266#endif // LOBBY_PROTOCOL_HPP
Used to store the needed data about the players that join a game. This class stores all the possible ...
Definition: game_setup.hpp:43
Base class for both client and server lobby. The lobbies are started when a server opens a game,...
Definition: lobby_protocol.hpp:47
float getRemainingVotingTime()
Returns the remaining voting time in seconds.
Definition: lobby_protocol.cpp:193
void startVotingPeriod(float max_time)
Starts the voting period time with the specified maximum time.
Definition: lobby_protocol.cpp:185
virtual void update(int ticks)=0
Called by the protocol listener, synchronously with the main loop.
std::map< uint32_t, PeerVote > m_peers_votes
Vote from each peer.
Definition: lobby_protocol.hpp:110
bool isVotingOver()
Returns if the voting period is over.
Definition: lobby_protocol.cpp:204
std::atomic< uint32_t > m_estimated_remaining_time
Estimated current started game remaining time, uint32_t max if not available.
Definition: lobby_protocol.hpp:124
static std::shared_ptr< T > get()
Returns the singleton client or server lobby protocol.
Definition: lobby_protocol.hpp:173
int m_last_live_join_util_ticks
Save the last live join ticks, for physical objects to update current transformation in server,...
Definition: lobby_protocol.hpp:132
int getNumberOfVotes() const
Returns the number of votes received so far.
Definition: lobby_protocol.hpp:219
GameSetup * getGameSetup() const
Returns the game setup data structure.
Definition: lobby_protocol.hpp:216
virtual void loadWorld()
Starts the sychronization protocol and the RaceEventManager.
Definition: lobby_protocol.cpp:74
static std::shared_ptr< Singleton > create(Types ...args)
Creates either a client or server lobby protocol as a singleton.
Definition: lobby_protocol.hpp:162
std::string m_current_track
Store current playing track in name.
Definition: lobby_protocol.hpp:138
std::atomic< uint64_t > m_end_voting_period
Timer user for voting periods in both lobbies.
Definition: lobby_protocol.hpp:113
static std::shared_ptr< T > getByType(ProcessType pt)
Returns specific singleton client or server lobby protocol.
Definition: lobby_protocol.hpp:187
float getMaxVotingTime()
Returns the maximum floating time in seconds.
Definition: lobby_protocol.hpp:213
virtual void setup()=0
A previous GameSetup is deleted and a new one is created.
Definition: lobby_protocol.cpp:170
GameSetup * m_game_setup
Stores data about the online game to play.
Definition: lobby_protocol.hpp:141
uint64_t m_max_voting_time
The maximum voting time.
Definition: lobby_protocol.hpp:116
const PeerVote * getVote(uint32_t host_id) const
Returns the voting data for one host.
Definition: lobby_protocol.cpp:223
std::mutex m_current_track_mutex
Mutex to protect m_current_track.
Definition: lobby_protocol.hpp:135
void addVote(uint32_t host_id, const PeerVote &vote)
Adds a vote.
Definition: lobby_protocol.cpp:214
const std::map< uint32_t, PeerVote > & getAllVotes() const
Returns all voting data.
Definition: lobby_protocol.hpp:228
std::atomic< uint32_t > m_estimated_progress
Estimated current started game progress in 0-100%, uint32_t max if not available.
Definition: lobby_protocol.hpp:128
Contains the profile of a player.
Definition: network_player_profile.hpp:42
A simple structure to store a vote from a client: track name, number of laps and reverse or not.
Definition: peer_vote.hpp:30
Abstract class used to define the global protocol functions.
Definition: protocol.hpp:92
Definition: remote_kart_info.hpp:51
Definition: singleton.hpp:87
Definition: track.hpp:114
Generic protocols declarations.