SuperTuxKart
Loading...
Searching...
No Matches
stk_peer.hpp
Go to the documentation of this file.
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
23#ifndef STK_PEER_HPP
24#define STK_PEER_HPP
25
26#include "utils/no_copy.hpp"
27#include "utils/time.hpp"
28#include "utils/types.hpp"
29
30#include <enet/enet.h>
31
32#include <array>
33#include <atomic>
34#include <deque>
35#include <memory>
36#include <numeric>
37#include <set>
38#include <string>
39#include <vector>
40
41class Crypto;
43class NetworkString;
44class STKHost;
45class SocketAddress;
46
47enum PeerDisconnectInfo : unsigned int
48{
53}; // PeerDisconnectInfo
54
55enum AddonScore : int
56{
57 AS_KART = 0,
58 AS_TRACK = 1,
59 AS_ARENA = 2,
60 AS_SOCCER = 3,
61 AS_TOTAL = 4,
62}; // AddonScore
63
64enum AlwaysSpectateMode : uint8_t
65{
69}; // AlwaysSpectateMode
70
75class STKPeer : public NoCopy
76{
77protected:
79 ENetPeer* m_enet_peer;
80
81 ENetAddress m_address;
82
84 std::atomic_bool m_validated;
85
87 std::atomic_bool m_waiting_for_game;
88
89 std::atomic_bool m_spectator;
90
91 std::atomic_bool m_disconnected;
92
93 std::atomic_bool m_warned_for_high_ping;
94
95 std::atomic<uint8_t> m_always_spectate;
96
98 uint32_t m_host_id;
99
100 std::unique_ptr<SocketAddress> m_socket_address;
101
102 STKHost* m_host;
103
104 std::vector<std::shared_ptr<NetworkPlayerProfile> > m_players;
105
106 uint64_t m_connected_time;
107
108 std::atomic<int64_t> m_last_activity;
109
110 std::atomic<int64_t> m_last_message;
111
112 int m_consecutive_messages;
113
115 std::pair<std::set<std::string>, std::set<std::string> > m_available_kts;
116
117 std::unique_ptr<Crypto> m_crypto;
118
119 std::deque<uint32_t> m_previous_pings;
120
121 std::atomic<uint32_t> m_average_ping;
122
123 std::atomic<int> m_packet_loss;
124
125 std::set<unsigned> m_available_kart_ids;
126
127 std::string m_user_version;
128
131 std::set<std::string> m_client_capabilities;
132
133 std::array<int, AS_TOTAL> m_addons_scores;
134public:
135 STKPeer(ENetPeer *enet_peer, STKHost* host, uint32_t host_id);
136 // ------------------------------------------------------------------------
137 ~STKPeer();
138 // ------------------------------------------------------------------------
139 void sendPacket(NetworkString *data, bool reliable = true,
140 bool encrypted = true);
141 // ------------------------------------------------------------------------
142 void disconnect();
143 // ------------------------------------------------------------------------
144 void kick();
145 // ------------------------------------------------------------------------
146 void reset();
147 // ------------------------------------------------------------------------
148 bool isConnected() const;
149 // ------------------------------------------------------------------------
150 bool isSamePeer(const STKPeer* peer) const;
151 bool isSamePeer(const ENetPeer* peer) const;
152 // ------------------------------------------------------------------------
153 std::vector<std::shared_ptr<NetworkPlayerProfile> >& getPlayerProfiles()
154 { return m_players; }
155 // ------------------------------------------------------------------------
156 bool hasPlayerProfiles() const { return !m_players.empty(); }
157 // ------------------------------------------------------------------------
158 void cleanPlayerProfiles() { m_players.clear(); }
159 // ------------------------------------------------------------------------
160 void addPlayer(std::shared_ptr<NetworkPlayerProfile> p)
161 { m_players.push_back(p); }
162 // ------------------------------------------------------------------------
163 void setValidated(bool val) { m_validated.store(val); }
164 // ------------------------------------------------------------------------
166 bool isValidated() const { return m_validated.load(); }
167 // ------------------------------------------------------------------------
169 uint32_t getHostId() const { return m_host_id; }
170 // ------------------------------------------------------------------------
171 float getConnectedTime() const
172 { return float(StkTime::getMonoTimeMs() - m_connected_time) / 1000.0f; }
173 // ------------------------------------------------------------------------
174 void setAvailableKartsTracks(std::set<std::string>& k,
175 std::set<std::string>& t)
176 { m_available_kts = std::make_pair(std::move(k), std::move(t)); }
177 // ------------------------------------------------------------------------
178 void eraseServerKarts(const std::set<std::string>& server_karts,
179 std::set<std::string>& karts_erase) const
180 {
181 if (m_available_kts.first.empty())
182 return;
183 for (const std::string& server_kart : server_karts)
184 {
185 if (m_available_kts.first.find(server_kart) ==
186 m_available_kts.first.end())
187 {
188 karts_erase.insert(server_kart);
189 }
190 }
191 }
192 // ------------------------------------------------------------------------
193 void eraseServerTracks(const std::set<std::string>& server_tracks,
194 std::set<std::string>& tracks_erase) const
195 {
196 if (m_available_kts.second.empty())
197 return;
198 for (const std::string& server_track : server_tracks)
199 {
200 if (m_available_kts.second.find(server_track) ==
201 m_available_kts.second.end())
202 {
203 tracks_erase.insert(server_track);
204 }
205 }
206 }
207 // ------------------------------------------------------------------------
208 std::pair<std::set<std::string>, std::set<std::string> >
209 getClientAssets() const { return m_available_kts; }
210 // ------------------------------------------------------------------------
211 void setPingInterval(uint32_t interval)
212 { enet_peer_ping_interval(m_enet_peer, interval); }
213 // ------------------------------------------------------------------------
214 uint32_t getPing();
215 // ------------------------------------------------------------------------
216 Crypto* getCrypto() const { return m_crypto.get(); }
217 // ------------------------------------------------------------------------
218 void setCrypto(std::unique_ptr<Crypto>&& c);
219 // ------------------------------------------------------------------------
220 uint32_t getAveragePing() const { return m_average_ping.load(); }
221 // ------------------------------------------------------------------------
222 ENetPeer* getENetPeer() const { return m_enet_peer; }
223 // ------------------------------------------------------------------------
224 void setWaitingForGame(bool val) { m_waiting_for_game.store(val); }
225 // ------------------------------------------------------------------------
226 bool isWaitingForGame() const { return m_waiting_for_game.load(); }
227 // ------------------------------------------------------------------------
228 void setSpectator(bool val) { m_spectator.store(val); }
229 // ------------------------------------------------------------------------
230 bool isSpectator() const { return m_spectator.load(); }
231 // ------------------------------------------------------------------------
232 bool isDisconnected() const { return m_disconnected.load(); }
233 // ------------------------------------------------------------------------
234 void setDisconnected(bool val) { return m_disconnected.store(val); }
235 // ------------------------------------------------------------------------
236 bool hasWarnedForHighPing() const { return m_warned_for_high_ping.load(); }
237 // ------------------------------------------------------------------------
238 void setWarnedForHighPing(bool val) { m_warned_for_high_ping.store(val); }
239 // ------------------------------------------------------------------------
240 void clearAvailableKartIDs() { m_available_kart_ids.clear(); }
241 // ------------------------------------------------------------------------
242 void addAvailableKartID(unsigned id) { m_available_kart_ids.insert(id); }
243 // ------------------------------------------------------------------------
244 bool availableKartID(unsigned id)
245 { return m_available_kart_ids.find(id) != m_available_kart_ids.end(); }
246 // ------------------------------------------------------------------------
247 const std::set<unsigned>& getAvailableKartIDs() const
248 { return m_available_kart_ids; }
249 // ------------------------------------------------------------------------
250 void setUserVersion(const std::string& uv) { m_user_version = uv; }
251 // ------------------------------------------------------------------------
252 const std::string& getUserVersion() const { return m_user_version; }
253 // ------------------------------------------------------------------------
254 void updateLastActivity()
255 { m_last_activity.store((int64_t)StkTime::getMonoTimeMs()); }
256 // ------------------------------------------------------------------------
257 int idleForSeconds() const
258 {
259 int64_t diff =
260 (int64_t)StkTime::getMonoTimeMs() - m_last_activity.load();
261 if (diff < 0)
262 return 0;
263 return (int)(diff / 1000);
264 }
265 // ------------------------------------------------------------------------
266 void setClientCapabilities(std::set<std::string>& caps)
267 { m_client_capabilities = std::move(caps); }
268 // ------------------------------------------------------------------------
269 const std::set<std::string>& getClientCapabilities() const
270 { return m_client_capabilities; }
271 // ------------------------------------------------------------------------
272 bool isAIPeer() const { return m_user_version == "AI"; }
273 // ------------------------------------------------------------------------
274 void setPacketLoss(int loss) { m_packet_loss.store(loss); }
275 // ------------------------------------------------------------------------
276 int getPacketLoss() const { return m_packet_loss.load(); }
277 // ------------------------------------------------------------------------
278 const std::array<int, AS_TOTAL>& getAddonsScores() const
279 { return m_addons_scores; }
280 // ------------------------------------------------------------------------
281 void setAddonsScores(const std::array<int, AS_TOTAL>& scores)
282 { m_addons_scores = scores; }
283 // ------------------------------------------------------------------------
284 void updateLastMessage()
285 { m_last_message.store((int64_t)StkTime::getMonoTimeMs()); }
286 // ------------------------------------------------------------------------
287 int64_t getLastMessage() const
288 { return m_last_message; }
289 // ------------------------------------------------------------------------
290 void updateConsecutiveMessages(bool too_fast)
291 {
292 if (too_fast)
293 m_consecutive_messages++;
294 else
295 m_consecutive_messages = 0;
296 }
297 // ------------------------------------------------------------------------
298 int getConsecutiveMessages() const { return m_consecutive_messages; }
299 // ------------------------------------------------------------------------
300 const SocketAddress& getAddress() const { return *m_socket_address.get(); }
301 // ------------------------------------------------------------------------
302 void setAlwaysSpectate(AlwaysSpectateMode mode)
303 { m_always_spectate.store(mode); }
304 // ------------------------------------------------------------------------
305 bool alwaysSpectate() const
306 { return m_always_spectate.load() != ASM_NONE; }
307 // ------------------------------------------------------------------------
308 void resetAlwaysSpectateFull()
309 {
310 if (m_always_spectate.load() == ASM_FULL)
311 m_always_spectate.store(ASM_NONE);
312 }
313}; // STKPeer
314
315#endif // STK_PEER_HPP
Contains the profile of a player.
Definition: network_player_profile.hpp:42
A new implementation of NetworkString, which has a fixed format: Byte 0: The type of the message,...
Definition: network_string.hpp:422
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:26
Represents the local host.
Definition: stk_host.hpp:73
Represents a peer. This class is used to interface the ENetPeer structure.
Definition: stk_peer.hpp:76
std::pair< std::set< std::string >, std::set< std::string > > m_available_kts
Available karts and tracks from this peer.
Definition: stk_peer.hpp:115
uint32_t getPing()
Returns the ping to this peer from host, it waits for 3 seconds for a stable ping returned by enet me...
Definition: stk_peer.cpp:165
bool isSamePeer(const STKPeer *peer) const
Returns if this STKPeer is the same as the given peer.
Definition: stk_peer.cpp:148
void reset()
Forcefully disconnects a peer (used by server).
Definition: stk_peer.cpp:89
void kick()
Kick this peer (used by server).
Definition: stk_peer.cpp:77
std::atomic_bool m_waiting_for_game
True if this peer is waiting for game.
Definition: stk_peer.hpp:87
void sendPacket(NetworkString *data, bool reliable=true, bool encrypted=true)
Sends a packet to this host.
Definition: stk_peer.cpp:103
bool isValidated() const
Returns if the client is validated by server.
Definition: stk_peer.hpp:166
bool isConnected() const
Returns if the peer is connected or not.
Definition: stk_peer.cpp:139
std::atomic_bool m_validated
True if this peer is validated by server.
Definition: stk_peer.hpp:84
std::set< std::string > m_client_capabilities
List of client capabilities set when connecting it, to determine features available in same version.
Definition: stk_peer.hpp:131
uint32_t m_host_id
Host id of this peer.
Definition: stk_peer.hpp:98
ENetPeer * m_enet_peer
Pointer to the corresponding ENet peer data structure.
Definition: stk_peer.hpp:79
uint32_t getHostId() const
Returns the host id of this peer.
Definition: stk_peer.hpp:169
Describes a IPv4 or IPv6 address in sockaddr_in(6) format, suitable in using with sendto.
Definition: socket_address.hpp:47
static uint64_t getMonoTimeMs()
Returns a time based since the starting of stk (monotonic clock).
Definition: time.hpp:106
PeerDisconnectInfo
Definition: stk_peer.hpp:48
@ PDI_TIMEOUT
Timeout disconnected (default in enet).
Definition: stk_peer.hpp:49
@ PDI_KICK
Kick disconnection.
Definition: stk_peer.hpp:51
@ PDI_NORMAL
Normal disconnction with acknowledgement.
Definition: stk_peer.hpp:50
@ PDI_KICK_HIGH_PING
Too high ping, kicked by server.
Definition: stk_peer.hpp:52
AlwaysSpectateMode
Definition: stk_peer.hpp:65
@ ASM_COMMAND
Set by player through command.
Definition: stk_peer.hpp:67
@ ASM_FULL
Set by server because too many players joined.
Definition: stk_peer.hpp:68
@ ASM_NONE
Default, not spectating at all.
Definition: stk_peer.hpp:66
Declares the general types that are used by the network.