2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
9 * @file tcp_game.h Basic functions to receive and send TCP packets for game purposes.
12 #ifndef NETWORK_CORE_TCP_GAME_H
13 #define NETWORK_CORE_TCP_GAME_H
15 #include "os_abstraction.h"
17 #include "../network_type.h"
18 #include "../../core/pool_type.hpp"
22 * Enum with all types of TCP packets.
23 * For the exact meaning, look at #NetworkGameSocketHandler.
25 enum PacketGameType
: uint8_t {
27 * These first ten packets must remain in this order for backward and forward compatibility
28 * between clients that are trying to join directly. These packets can be received and/or sent
29 * by the server before the server has processed the 'join' packet from the client.
32 /* Packets sent by socket accepting code without ever constructing a client socket instance. */
33 PACKET_SERVER_FULL
, ///< The server is full and has no place for you.
34 PACKET_SERVER_BANNED
, ///< The server has banned you.
36 /* Packets used by the client to join and an error message when the revision is wrong. */
37 PACKET_CLIENT_JOIN
, ///< The client telling the server it wants to join.
38 PACKET_SERVER_ERROR
, ///< Server sending an error message to the client.
40 /* Unused packet types, formerly used for the pre-game lobby. */
41 PACKET_CLIENT_UNUSED
, ///< Unused.
42 PACKET_SERVER_UNUSED
, ///< Unused.
44 /* Packets used to get the game info. */
45 PACKET_SERVER_GAME_INFO
, ///< Information about the server.
46 PACKET_CLIENT_GAME_INFO
, ///< Request information about the server.
48 /* A server quitting this game. */
49 PACKET_SERVER_NEWGAME
, ///< The server is preparing to start a new game.
50 PACKET_SERVER_SHUTDOWN
, ///< The server is shutting down.
53 * Packets after here assume that the client
54 * and server are running the same version. As
55 * such ordering is unimportant from here on.
57 * The following is the remainder of the packets
58 * sent as part of authenticating and getting
59 * the map and other important data.
62 /* After the join step, the first perform game authentication and enabling encryption. */
63 PACKET_SERVER_AUTH_REQUEST
, ///< The server requests the client to authenticate using a number of methods.
64 PACKET_CLIENT_AUTH_RESPONSE
, ///< The client responds to the authentication request.
65 PACKET_SERVER_ENABLE_ENCRYPTION
, ///< The server tells that authentication has completed and requests to enable encryption with the keys of the last \c PACKET_CLIENT_AUTH_RESPONSE.
67 /* After the authentication is done, the next step is identification. */
68 PACKET_CLIENT_IDENTIFY
, ///< Client telling the server the client's name and requested company.
70 /* After the identify step, the next is checking NewGRFs. */
71 PACKET_SERVER_CHECK_NEWGRFS
, ///< Server sends NewGRF IDs and MD5 checksums for the client to check.
72 PACKET_CLIENT_NEWGRFS_CHECKED
, ///< Client acknowledges that it has all required NewGRFs.
74 /* The server welcomes the authenticated client and sends information of other clients. */
75 PACKET_SERVER_WELCOME
, ///< Server welcomes you and gives you your #ClientID.
76 PACKET_SERVER_CLIENT_INFO
, ///< Server sends you information about a client.
78 /* Getting the savegame/map. */
79 PACKET_CLIENT_GETMAP
, ///< Client requests the actual map.
80 PACKET_SERVER_WAIT
, ///< Server tells the client there are some people waiting for the map as well.
81 PACKET_SERVER_MAP_BEGIN
, ///< Server tells the client that it is beginning to send the map.
82 PACKET_SERVER_MAP_SIZE
, ///< Server tells the client what the (compressed) size of the map is.
83 PACKET_SERVER_MAP_DATA
, ///< Server sends bits of the map to the client.
84 PACKET_SERVER_MAP_DONE
, ///< Server tells it has just sent the last bits of the map to the client.
85 PACKET_CLIENT_MAP_OK
, ///< Client tells the server that it received the whole map.
87 PACKET_SERVER_JOIN
, ///< Tells clients that a new client has joined.
90 * At this moment the client has the map and
91 * the client is fully authenticated. Now the
92 * normal communication starts.
95 /* Game progress monitoring. */
96 PACKET_SERVER_FRAME
, ///< Server tells the client what frame it is in, and thus to where the client may progress.
97 PACKET_CLIENT_ACK
, ///< The client tells the server which frame it has executed.
98 PACKET_SERVER_SYNC
, ///< Server tells the client what the random state should be.
100 /* Sending commands around. */
101 PACKET_CLIENT_COMMAND
, ///< Client executed a command and sends it to the server.
102 PACKET_SERVER_COMMAND
, ///< Server distributes a command to (all) the clients.
104 /* Human communication! */
105 PACKET_CLIENT_CHAT
, ///< Client said something that should be distributed.
106 PACKET_SERVER_CHAT
, ///< Server distributing the message of a client (or itself).
107 PACKET_SERVER_EXTERNAL_CHAT
, ///< Server distributing the message from external source.
109 /* Remote console. */
110 PACKET_CLIENT_RCON
, ///< Client asks the server to execute some command.
111 PACKET_SERVER_RCON
, ///< Response of the executed command on the server.
113 /* Moving a client.*/
114 PACKET_CLIENT_MOVE
, ///< A client would like to be moved to another company.
115 PACKET_SERVER_MOVE
, ///< Server tells everyone that someone is moved to another company.
117 /* Configuration updates. */
118 PACKET_CLIENT_SET_NAME
, ///< A client changes its name.
119 PACKET_SERVER_CONFIG_UPDATE
, ///< Some network configuration important to the client changed.
121 /* A client quitting. */
122 PACKET_CLIENT_QUIT
, ///< A client tells the server it is going to quit.
123 PACKET_SERVER_QUIT
, ///< A server tells that a client has quit.
124 PACKET_CLIENT_ERROR
, ///< A client reports an error to the server.
125 PACKET_SERVER_ERROR_QUIT
, ///< A server tells that a client has hit an error and did quit.
127 PACKET_END
, ///< Must ALWAYS be on the end of this list!! (period)
130 /** Packet that wraps a command */
131 struct CommandPacket
;
134 * A "queue" of CommandPackets.
135 * Not a std::queue because, when paused, some commands remain on the queue.
136 * In other words, you do not always pop the first element from this queue.
138 using CommandQueue
= std::vector
<CommandPacket
>;
140 /** Base socket handler for all TCP sockets */
141 class NetworkGameSocketHandler
: public NetworkTCPSocketHandler
{
142 /* TODO: rewrite into a proper class */
144 NetworkClientInfo
*info
; ///< Client info related to this socket
145 bool is_pending_deletion
= false; ///< Whether this socket is pending deletion
148 NetworkRecvStatus
ReceiveInvalidPacket(PacketGameType type
);
151 * Notification that the server is full.
152 * @param p The packet that was just received.
154 virtual NetworkRecvStatus
Receive_SERVER_FULL(Packet
&p
);
157 * Notification that the client trying to join is banned.
158 * @param p The packet that was just received.
160 virtual NetworkRecvStatus
Receive_SERVER_BANNED(Packet
&p
);
163 * Try to join the server:
164 * string OpenTTD revision (norev0000 if no revision).
165 * uint32_t NewGRF version (added in 1.2).
166 * string Name of the client (max NETWORK_NAME_LENGTH) (removed in 15).
167 * uint8_t ID of the company to play as (1..MAX_COMPANIES) (removed in 15).
168 * uint8_t ID of the clients Language (removed in 15).
169 * string Client's unique identifier (removed in 1.0).
171 * @param p The packet that was just received.
173 virtual NetworkRecvStatus
Receive_CLIENT_JOIN(Packet
&p
);
176 * The client made an error:
177 * uint8_t Error code caused (see NetworkErrorCode).
178 * @param p The packet that was just received.
180 virtual NetworkRecvStatus
Receive_SERVER_ERROR(Packet
&p
);
183 * Request game information.
184 * @param p The packet that was just received.
186 virtual NetworkRecvStatus
Receive_CLIENT_GAME_INFO(Packet
&p
);
189 * Sends information about the game.
190 * Serialized NetworkGameInfo. See game_info.h for details.
191 * @param p The packet that was just received.
193 virtual NetworkRecvStatus
Receive_SERVER_GAME_INFO(Packet
&p
);
196 * Send information about a client:
197 * uint32_t ID of the client (always unique on a server. 1 = server, 0 is invalid).
198 * uint8_t ID of the company the client is playing as (255 for spectators).
199 * string Name of the client.
200 * string Public key of the client.
201 * @param p The packet that was just received.
203 virtual NetworkRecvStatus
Receive_SERVER_CLIENT_INFO(Packet
&p
);
206 * The client tells the server about the identity of the client:
207 * string Name of the client (max NETWORK_NAME_LENGTH).
208 * uint8_t ID of the company to play as (1..MAX_COMPANIES, or COMPANY_SPECTATOR).
209 * @param p The packet that was just received.
211 virtual NetworkRecvStatus
Receive_CLIENT_IDENTIFY(Packet
&p
);
214 * Indication to the client that it needs to authenticate:
215 * uint8_t The \c NetworkAuthenticationMethod to use.
216 * 32 * uint8_t Public key of the server.
217 * 24 * uint8_t Nonce for the key exchange.
218 * @param p The packet that was just received.
220 virtual NetworkRecvStatus
Receive_SERVER_AUTH_REQUEST(Packet
&p
);
223 * Send the response to the authentication request:
224 * 32 * uint8_t Public key of the client.
225 * 16 * uint8_t Message authentication code.
226 * 8 * uint8_t Random message that got encoded and signed.
227 * @param p The packet that was just received.
229 virtual NetworkRecvStatus
Receive_CLIENT_AUTH_RESPONSE(Packet
&p
);
232 * Indication to the client that authentication is complete and encryption has to be used from here on forward.
233 * The encryption uses the shared keys generated by the last AUTH_REQUEST key exchange.
234 * 24 * uint8_t Nonce for encrypted connection.
235 * @param p The packet that was just received.
237 virtual NetworkRecvStatus
Receive_SERVER_ENABLE_ENCRYPTION(Packet
&p
);
240 * The client is joined and ready to receive their map:
241 * uint32_t Own client ID.
242 * @param p The packet that was just received.
244 virtual NetworkRecvStatus
Receive_SERVER_WELCOME(Packet
&p
);
247 * Request the map from the server.
248 * @param p The packet that was just received.
250 virtual NetworkRecvStatus
Receive_CLIENT_GETMAP(Packet
&p
);
253 * Notification that another client is currently receiving the map:
254 * uint8_t Number of clients waiting in front of you.
255 * @param p The packet that was just received.
257 virtual NetworkRecvStatus
Receive_SERVER_WAIT(Packet
&p
);
260 * Sends that the server will begin with sending the map to the client:
261 * uint32_t Current frame.
262 * @param p The packet that was just received.
264 virtual NetworkRecvStatus
Receive_SERVER_MAP_BEGIN(Packet
&p
);
267 * Sends the size of the map to the client.
268 * uint32_t Size of the (compressed) map (in bytes).
269 * @param p The packet that was just received.
271 virtual NetworkRecvStatus
Receive_SERVER_MAP_SIZE(Packet
&p
);
274 * Sends the data of the map to the client:
275 * Contains a part of the map (until max size of packet).
276 * @param p The packet that was just received.
278 virtual NetworkRecvStatus
Receive_SERVER_MAP_DATA(Packet
&p
);
281 * Sends that all data of the map are sent to the client:
282 * @param p The packet that was just received.
284 virtual NetworkRecvStatus
Receive_SERVER_MAP_DONE(Packet
&p
);
287 * Tell the server that we are done receiving/loading the map.
288 * @param p The packet that was just received.
290 virtual NetworkRecvStatus
Receive_CLIENT_MAP_OK(Packet
&p
);
293 * A client joined (PACKET_CLIENT_MAP_OK), what usually directly follows is a PACKET_SERVER_CLIENT_INFO:
294 * uint32_t ID of the client that just joined the game.
295 * @param p The packet that was just received.
297 virtual NetworkRecvStatus
Receive_SERVER_JOIN(Packet
&p
);
300 * Sends the current frame counter to the client:
301 * uint32_t Frame counter
302 * uint32_t Frame counter max (how far may the client walk before the server?)
303 * uint32_t General seed 1 (dependent on compile settings, not default).
304 * uint32_t General seed 2 (dependent on compile settings, not default).
305 * uint8_t Random token to validate the client is actually listening (only occasionally present).
306 * @param p The packet that was just received.
308 virtual NetworkRecvStatus
Receive_SERVER_FRAME(Packet
&p
);
311 * Sends a sync-check to the client:
312 * uint32_t Frame counter.
313 * uint32_t General seed 1.
314 * uint32_t General seed 2 (dependent on compile settings, not default).
315 * @param p The packet that was just received.
317 virtual NetworkRecvStatus
Receive_SERVER_SYNC(Packet
&p
);
320 * Tell the server we are done with this frame:
321 * uint32_t Current frame counter of the client.
322 * uint8_t The random token that the server sent in the PACKET_SERVER_FRAME packet.
323 * @param p The packet that was just received.
325 virtual NetworkRecvStatus
Receive_CLIENT_ACK(Packet
&p
);
328 * Send a DoCommand to the Server:
329 * uint8_t ID of the company (0..MAX_COMPANIES-1).
330 * uint32_t ID of the command (see command.h).
331 * <var> Command specific buffer with encoded parameters of variable length.
332 * The content differs per command and can change without notification.
333 * uint8_t ID of the callback.
334 * @param p The packet that was just received.
336 virtual NetworkRecvStatus
Receive_CLIENT_COMMAND(Packet
&p
);
339 * Sends a DoCommand to the client:
340 * uint8_t ID of the company (0..MAX_COMPANIES-1).
341 * uint32_t ID of the command (see command.h).
342 * <var> Command specific buffer with encoded parameters of variable length.
343 * The content differs per command and can change without notification.
344 * uint8_t ID of the callback.
345 * uint32_t Frame of execution.
346 * @param p The packet that was just received.
348 virtual NetworkRecvStatus
Receive_SERVER_COMMAND(Packet
&p
);
351 * Sends a chat-packet to the server:
352 * uint8_t ID of the action (see NetworkAction).
353 * uint8_t ID of the destination type (see DestType).
354 * uint32_t ID of the client or company (destination of the chat).
355 * string Message (max NETWORK_CHAT_LENGTH).
356 * uint64_t data (used e.g. for 'give money' actions).
357 * @param p The packet that was just received.
359 virtual NetworkRecvStatus
Receive_CLIENT_CHAT(Packet
&p
);
362 * Sends a chat-packet to the client:
363 * uint8_t ID of the action (see NetworkAction).
364 * uint32_t ID of the client (origin of the chat).
365 * string Message (max NETWORK_CHAT_LENGTH).
366 * uint64_t data (used e.g. for 'give money' actions).
367 * @param p The packet that was just received.
369 virtual NetworkRecvStatus
Receive_SERVER_CHAT(Packet
&p
);
372 * Sends a chat-packet for external source to the client:
373 * string Name of the source this message came from.
374 * uint16_t TextColour to use for the message.
375 * string Name of the user who sent the messsage.
376 * string Message (max NETWORK_CHAT_LENGTH).
377 * @param p The packet that was just received.
379 virtual NetworkRecvStatus
Receive_SERVER_EXTERNAL_CHAT(Packet
&p
);
382 * Gives the client a new name:
383 * string New name of the client.
384 * @param p The packet that was just received.
386 virtual NetworkRecvStatus
Receive_CLIENT_SET_NAME(Packet
&p
);
389 * The client is quitting the game.
390 * @param p The packet that was just received.
392 virtual NetworkRecvStatus
Receive_CLIENT_QUIT(Packet
&p
);
395 * The client made an error and is quitting the game.
396 * uint8_t Error of the code caused (see NetworkErrorCode).
397 * @param p The packet that was just received.
399 virtual NetworkRecvStatus
Receive_CLIENT_ERROR(Packet
&p
);
402 * Notification that a client left the game:
403 * uint32_t ID of the client.
404 * @param p The packet that was just received.
406 virtual NetworkRecvStatus
Receive_SERVER_QUIT(Packet
&p
);
409 * Inform all clients that one client made an error and thus has quit/been disconnected:
410 * uint32_t ID of the client that caused the error.
411 * uint8_t Code of the error caused (see NetworkErrorCode).
412 * @param p The packet that was just received.
414 virtual NetworkRecvStatus
Receive_SERVER_ERROR_QUIT(Packet
&p
);
417 * Let the clients know that the server is closing.
418 * @param p The packet that was just received.
420 virtual NetworkRecvStatus
Receive_SERVER_SHUTDOWN(Packet
&p
);
423 * Let the clients know that the server is loading a new map.
424 * @param p The packet that was just received.
426 virtual NetworkRecvStatus
Receive_SERVER_NEWGAME(Packet
&p
);
429 * Send the result of an issues RCon command back to the client:
430 * uint16_t Colour code.
431 * string Output of the RCon command
432 * @param p The packet that was just received.
434 virtual NetworkRecvStatus
Receive_SERVER_RCON(Packet
&p
);
437 * Send an RCon command to the server:
438 * string RCon password.
439 * string Command to be executed.
440 * @param p The packet that was just received.
442 virtual NetworkRecvStatus
Receive_CLIENT_RCON(Packet
&p
);
445 * Sends information about all used GRFs to the client:
446 * uint8_t Amount of GRFs (the following data is repeated this many times, i.e. per GRF data).
448 * 16 * uint8_t MD5 checksum of the GRF
449 * @param p The packet that was just received.
451 virtual NetworkRecvStatus
Receive_SERVER_CHECK_NEWGRFS(Packet
&p
);
454 * Tell the server that we have the required GRFs
455 * @param p The packet that was just received.
457 virtual NetworkRecvStatus
Receive_CLIENT_NEWGRFS_CHECKED(Packet
&p
);
460 * Move a client from one company into another:
461 * uint32_t ID of the client.
462 * uint8_t ID of the new company.
463 * @param p The packet that was just received.
465 virtual NetworkRecvStatus
Receive_SERVER_MOVE(Packet
&p
);
468 * Request the server to move this client into another company:
469 * uint8_t ID of the company the client wants to join.
470 * @param p The packet that was just received.
472 virtual NetworkRecvStatus
Receive_CLIENT_MOVE(Packet
&p
);
475 * Update the clients knowledge of the max settings:
476 * uint8_t Maximum number of companies allowed.
477 * uint8_t Maximum number of spectators allowed.
478 * @param p The packet that was just received.
480 virtual NetworkRecvStatus
Receive_SERVER_CONFIG_UPDATE(Packet
&p
);
482 NetworkRecvStatus
HandlePacket(Packet
&p
);
484 NetworkGameSocketHandler(SOCKET s
);
486 ClientID client_id
; ///< Client identifier
487 uint32_t last_frame
; ///< Last frame we have executed
488 uint32_t last_frame_server
; ///< Last frame the server has executed
489 CommandQueue incoming_queue
; ///< The command-queue awaiting handling
490 std::chrono::steady_clock::time_point last_packet
; ///< Time we received the last frame.
492 NetworkRecvStatus
CloseConnection(bool error
= true) override
;
495 * Close the network connection due to the given status.
496 * @param status The reason the connection got closed.
498 virtual NetworkRecvStatus
CloseConnection(NetworkRecvStatus status
) = 0;
499 virtual ~NetworkGameSocketHandler() = default;
502 * Sets the client info for this socket handler.
503 * @param info The new client info.
505 inline void SetInfo(NetworkClientInfo
*info
)
507 assert(info
!= nullptr && this->info
== nullptr);
512 * Gets the client info of this socket handler.
513 * @return The client info.
515 inline NetworkClientInfo
*GetInfo() const
520 NetworkRecvStatus
ReceivePackets();
522 const char *ReceiveCommand(Packet
&p
, CommandPacket
&cp
);
523 void SendCommand(Packet
&p
, const CommandPacket
&cp
);
525 bool IsPendingDeletion() const { return this->is_pending_deletion
; }
527 void DeferDeletion();
528 static void ProcessDeferredDeletions();
531 #endif /* NETWORK_CORE_TCP_GAME_H */