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