1 #pragma once
2 
3 /**
4  * @file
5  * This file describes the protocol that is used for network communication.
6  * It contains structures and serializations that are transmitted.
7  *
8  * Implementation notes:
9  *   - First member must be uint8_t packet_type
10  *   - Serialization is basically a naive memcpy, so use only primitive types
11  */
12 
13 #include <boost/lexical_cast.hpp>
14 #include "../vdrift/mathvector.h"
15 #include "../vdrift/quaternion.h"
16 #include "types.hpp"
17 #include "address.hpp"
18 
19 namespace protocol {
20 
21 // Check the comments in the packet structs to find out which one of these they affect.
22 const uint32_t GAME_PROTOCOL_VERSION = 4;
23 const uint32_t MASTER_PROTOCOL_VERSION = 6;
24 
25 const unsigned DEFAULT_PORT = 4243;
26 
27 
28 /**
29  * @brief Contains all possible message types.
30  * It will be transmitted as 8-bit unsigned int.
31  * On change, bump GAME_PROTOCOL_VERSION, MASTER_PROTOCOL_VERSION
32  */
33 enum PacketType
34 {
35 	HANDSHAKE = 0,
36 	PING,
37 	PONG,
38 	PEER_ADDRESS,       // Packet for peer discovery
39 	PLAYER_INFO,        // Player attributes of the sender
40 	TEXT_MESSAGE,       // Text string that should be displayed somewhere
41 	CAR_UPDATE,         // Car state update
42 	GAME_LIST,          // Client requests master server to list games
43 	GAME_ACCEPTED,      // Master server sends response for newly accepted games
44 	GAME_STATUS,        // An available game (either client updates, or server reports)
45 	START_GAME,         // Signal to start loading the game
46 	START_COUNTDOWN,    // Signal that loading has finished, start race
47 	TIME_INFO,          // Lap / race time info
48 	RETURN_LOBBY        // Signal to go back to lobby
49 };
50 
51 
52 /**
53  * @brief Contains error codes that tell the reason of disconnecting.
54  */
55 enum ErrorCodes
56 {
57 	WRONG_PASSWORD = 1,
58 	INCOMPATIBLE_GAME_PROTOCOL,
59 	INCOMPATIBLE_MASTER_PROTOCOL
60 };
61 
62 /**
63  * @brief Contains authentication etc. info.
64  * This stuff needs to be validated before accepting a new connection as a peer.
65  * On change, bump GAME_PROTOCOL_VERSION
66  */
67 struct HandshakePackage
68 {
69 	uint8_t packet_type;
70 	uint32_t master_protocol_version;
71 	uint32_t game_protocol_version;
72 	char password[16];
73 
HandshakePackageprotocol::HandshakePackage74 	HandshakePackage(std::string passwd = "")
75 		:packet_type(HANDSHAKE)
76 		,master_protocol_version(MASTER_PROTOCOL_VERSION)
77 		,game_protocol_version(GAME_PROTOCOL_VERSION)
78 	{
79 		memset(password, 0, sizeof(password));
80 		strcpy(password, passwd.c_str());
81 	}
82 };
83 
84 
85 /**
86  * @brief Contains information about one game that is available for joining.
87  * On change, bump GAME_PROTOCOL_VERSION, MASTER_PROTOCOL_VERSION
88  */
89 struct GameInfo
90 {
91 	uint8_t packet_type;
92 	uint32_t id;        // Set by server
93 	uint32_t address;   // Set by server
94 	uint16_t port;      // Set by client
95 	uint32_t timestamp; // Set by server
96 
97 	uint8_t players;    // Set by client, all below
98 	uint8_t collisions;
99 	uint8_t laps;
100 	uint8_t locked;    // game
101 	uint8_t reversed;  // track
102 
103 	uint8_t flip_type;
104 	uint8_t boost_type;  float boost_power;
105 	char name[32], track[32], sim_mode[32];
106 
107 	uint8_t start_order;
108 	uint8_t tree_collis;  float tree_mult;   // trees setup from host
109 	uint8_t damage_type, rewind_type;
110 	float damage_lap_dec, boost_lap_inc, rewind_lap_inc;  //todo
111 
GameInfoprotocol::GameInfo112 	GameInfo()
113 		:packet_type(GAME_STATUS), id(0), address(0), port(0), timestamp(0)
114 		,players(0), collisions(0), laps(0), locked(0), reversed(0)
115 		,flip_type(0), boost_type(0), boost_power(0.8f)
116 		,start_order(0)
117 		,tree_collis(0), tree_mult(1.f)
118 		,damage_type(0), rewind_type(0)
119 		,damage_lap_dec(0), boost_lap_inc(0), rewind_lap_inc(0)
120 	{
121 		name[0] = '\0';  track[0] = '\0';  track[31] = '\0';  sim_mode[0] = '\0';
122 	}
123 
operator ==protocol::GameInfo124 	bool operator==(const GameInfo& other) {  return id == other.id;  }
operator !=protocol::GameInfo125 	bool operator!=(const GameInfo& other) {  return !(*this == other);  }
operator boolprotocol::GameInfo126 	operator bool() {  return id > 0;  }
127 };
128 
129 typedef std::map<uint32_t, protocol::GameInfo> GameList;
130 
131 
132 /**
133  * @brief Contains the address of a peer to connect.
134  * These structs are passed around to create the complete network topography.
135  * On change, bump GAME_PROTOCOL_VERSION
136  */
137 struct PeerAddressPacket
138 {
139 	uint8_t packet_type;
140 	net::Address address;
141 
PeerAddressPacketprotocol::PeerAddressPacket142 	PeerAddressPacket(net::Address addr = net::Address())
143 		:packet_type(PEER_ADDRESS), address(addr)
144 	{	}
145 
operator ==protocol::PeerAddressPacket146 	bool operator==(const PeerAddressPacket& other) {  return address == other.address;  }
operator !=protocol::PeerAddressPacket147 	bool operator!=(const PeerAddressPacket& other) {  return !(*this == other);  }
148 };
149 
150 
151 /**
152  * @brief Contains player info.
153  * These structs are passed around to update player information.
154  * On change, bump GAME_PROTOCOL_VERSION
155  */
156 struct PlayerInfoPacket
157 {
158 	uint8_t packet_type;
159 	int32_t random_id;
160 	char name[16];
161 	char car[10];
162 	char password[16];
163 	uint8_t peers;
164 	uint8_t ready;
165 	//TODO:  car colors (also change nick colors in game tab)
166 	//float car_hue, car_sat, car_val, car_gloss, car_refl;  // car color
167 
PlayerInfoPacketprotocol::PlayerInfoPacket168 	PlayerInfoPacket()
169 		:packet_type(PLAYER_INFO), random_id(-1), ready(), peers()
170 	{
171 		memset(name, 0, sizeof(name));
172 		memset(car, 0, sizeof(car));
173 		memset(password, 0, sizeof(password));
174 	}
175 };
176 
177 
178 /**
179  * @brief Contains the car state.
180  * These structs are passed around to update car position etc.
181  * On change, bump GAME_PROTOCOL_VERSION
182  */
183 struct CarStatePackage
184 {
185 	uint8_t packet_type;
186 	MATHVECTOR<float,3> pos;
187 	QUATERNION<float> rot;
188 	MATHVECTOR<float,3> linearVel;
189 	MATHVECTOR<float,3> angularVel;
190 
191 	float steer;
192 	uint8_t trackPercent;
193 	uint8_t boost;
194 	uint8_t brake;
195 	//uint8_t damage;  //todo:..
196 	// boostFuel,gear, vel,rpm for replays ?..
197 
CarStatePackageprotocol::CarStatePackage198 	CarStatePackage()
199 		:packet_type(CAR_UPDATE)
200 		,steer(0.f),trackPercent(0),boost(0),brake(0)
201 	{	}
operator boolprotocol::CarStatePackage202 	operator bool()
203 	{	return packet_type == CAR_UPDATE;  }
204 };
205 
206 typedef std::map<int8_t, CarStatePackage> CarStates;
207 
208 
209 /**
210  * @brief Contains lap / race timing info.
211  * On change, bump GAME_PROTOCOL_VERSION
212  */
213 struct TimeInfoPackage
214 {
215 	uint8_t packet_type;
216 	uint8_t lap; // 0 for total time
217 	double time;
218 
TimeInfoPackageprotocol::TimeInfoPackage219 	TimeInfoPackage(uint8_t initLap, double initTime):
220 		packet_type(TIME_INFO), lap(initLap), time(initTime)
221 	{	}
222 };
223 
224 
225 } // namespace protocol
226