1 /*
2  *  Copyright 2006  Serge van den Boom <svdb@stack.nl>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #ifndef UQM_SUPERMELEE_NETPLAY_PACKET_H_
20 #define UQM_SUPERMELEE_NETPLAY_PACKET_H_
21 
22 #if defined(__cplusplus)
23 extern "C" {
24 #endif
25 
26 typedef struct Packet Packet;
27 
28 typedef enum PacketType {
29 	PACKET_INIT,
30 	PACKET_PING,
31 	PACKET_ACK,
32 	PACKET_READY,
33 	PACKET_FLEET,
34 	PACKET_TEAMNAME,
35 	PACKET_HANDSHAKE0,
36 	PACKET_HANDSHAKE1,
37 	PACKET_HANDSHAKECANCEL,
38 	PACKET_HANDSHAKECANCELACK,
39 	PACKET_SEEDRANDOM,
40 	PACKET_INPUTDELAY,
41 	PACKET_SELECTSHIP,
42 	PACKET_BATTLEINPUT,
43 	PACKET_FRAMECOUNT,
44 	PACKET_CHECKSUM,
45 	PACKET_ABORT,
46 	PACKET_RESET,
47 
48 	PACKET_NUM, /* Number of packet types */
49 } PacketType;
50 
51 // Sent before aborting the connection.
52 typedef enum NetplayAbortReason {
53 	AbortReason_unspecified,
54 	AbortReason_versionMismatch,
55 	AbortReason_invalidHash,
56 	AbortReason_protocolError,
57 			// Network is in an inconsistent state.
58 } NetplayAbortReason;
59 
60 // Sent before resetting the connection. A game in progress is terminated.
61 typedef enum NetplayResetReason {
62 	ResetReason_unspecified,
63 	ResetReason_syncLoss,
64 	ResetReason_manualReset,
65 } NetplayResetReason;
66 
67 #if defined(__cplusplus)
68 }
69 #endif
70 
71 #ifndef PACKET_H_STANDALONE
72 #include "netconnection.h"
73 
74 #include "types.h"
75 #include "libs/network/bytesex.h"
76 
77 #if defined(__cplusplus)
78 extern "C" {
79 #endif
80 
81 /* NB: These handlers are expected not to modify the state if an
82  *     error occurs.
83  * When a handler is called, it has already been validated that the
84  * a complete packet has arrived.
85  */
86 typedef int (*PacketHandler)(NetConnection *conn, const void *packet);
87 
88 typedef struct {
89 	size_t len;  /* Minimal length of a packet of this type */
90 	PacketHandler handler;
91 	const char *name;
92 } PacketTypeData;
93 
94 extern PacketTypeData packetTypeData[];
95 
96 #if defined(__cplusplus)
97 }
98 #endif
99 
100 #endif
101 
102 #if defined(__cplusplus)
103 extern "C" {
104 #endif
105 
106 // When adding new packets, be sure to have all the fields properly aligned,
107 // and that the size of a packet is a multiple of 4 bytes in length.
108 // Fields should be no longer than 4 bytes in themselves, as larger
109 // fields may require a larger alignment.
110 
111 typedef struct {
112 	uint16 len;
113 	uint16 type;  /* Actually of type PacketType */
114 } PacketHeader;
115 
116 // "Base class" for all packets.
117 struct Packet {
118 	PacketHeader header;
119 };
120 
121 static inline size_t
packetLength(const Packet * packet)122 packetLength(const Packet *packet) {
123 	return (size_t) ntoh16(packet->header.len);
124 }
125 
126 static inline PacketType
packetType(const Packet * packet)127 packetType(const Packet *packet) {
128 	return (PacketType) (int) ntoh16(packet->header.type);
129 }
130 
131 static inline bool
validPacketType(PacketType type)132 validPacketType(PacketType type) {
133 	return type < PACKET_NUM;
134 }
135 
136 typedef struct {
137 	PacketHeader header;
138 	struct {
139 		uint8 major;
140 		uint8 minor;
141 	} protoVersion; /* Protocol version */
142 	uint16 padding0;  /* Set to 0 */
143 	struct {
144 		uint8 major;
145 		uint8 minor;
146 		uint8 patch;
147 	} uqmVersion; /* Protocol version */
148 	uint8 padding1;  /* Set to 0 */
149 } Packet_Init;
150 
151 typedef struct {
152 	PacketHeader header;
153 	uint32 id;
154 } Packet_Ping;
155 
156 // Acknowledgement of a Ping.
157 typedef struct {
158 	PacketHeader header;
159 	uint32 id;
160 } Packet_Ack;
161 
162 // Used to signal that a party is ready to continue.
163 typedef struct {
164 	PacketHeader header;
165 	// No contents.
166 } Packet_Ready;
167 
168 typedef struct {
169 	PacketHeader header;
170 	uint32 seed;
171 } Packet_SeedRandom;
172 
173 typedef struct {
174 	PacketHeader header;
175 	uint32 delay;
176 } Packet_InputDelay;
177 
178 // This enum is used to indicate that a packet containing it relates to
179 // either the local or the remote player, from the perspective of the
180 // sender of the message;
181 typedef enum {
182 	NetplaySide_local,
183 	NetplaySide_remote
184 } NetplaySide;
185 
186 typedef struct {
187 	uint8 index;  /* Position in the fleet */
188 	uint8 ship;   /* Ship type index; actually MeleeShip */
189 } FleetEntry;
190 // Structure describing an update to a player's fleet.
191 // TODO: use strings as ship identifiers, instead of numbers,
192 // so that adding of new ships doesn't break this.
193 typedef struct {
194 	PacketHeader header;
195 	uint8 side;
196 	uint8 padding;
197 	uint16 numShips;
198 	FleetEntry ships[];
199 	// Be sure to add padding to this structure to make it a multiple of
200 	// 4 bytes in length.
201 } Packet_Fleet;
202 
203 typedef struct {
204 	PacketHeader header;
205 	uint8 side;
206 	uint8 padding;
207 	uint8 name[];
208 			// '\0' terminated.
209 	// Be sure to add padding to this structure to make it a multiple of
210 	// 4 bytes in length.
211 } Packet_TeamName;
212 
213 typedef struct {
214 	PacketHeader header;
215 	// No contents.
216 } Packet_Handshake0;
217 
218 typedef struct {
219 	PacketHeader header;
220 	// No contents.
221 } Packet_Handshake1;
222 
223 typedef struct {
224 	PacketHeader header;
225 	// No contents.
226 } Packet_HandshakeCancel;
227 
228 typedef struct {
229 	PacketHeader header;
230 	// No contents.
231 } Packet_HandshakeCancelAck;
232 
233 typedef struct {
234 	PacketHeader header;
235 	uint16 ship;
236 			// The value '(uint16) ~0' indicates random selection.
237 	uint16 padding;
238 } Packet_SelectShip;
239 
240 typedef struct {
241 	PacketHeader header;
242 	uint8 state;  /* Actually BATTLE_INPUT_STATE */
243 	uint8 padding0;
244 	uint16 padding1;
245 } Packet_BattleInput;
246 
247 typedef struct {
248 	PacketHeader header;
249 	uint32 frameCount;  /* Actually BattleFrameCounter */
250 } Packet_FrameCount;
251 
252 typedef struct {
253 	PacketHeader header;
254 	uint32 frameNr;  /* Actually BattleFrameCounter */
255 	uint32 checksum;  /* Actually Checksum */
256 } Packet_Checksum;
257 
258 typedef struct {
259 	PacketHeader header;
260 	uint16 reason;  /* Actually NetplayAbortReason */
261 	uint16 padding0;
262 } Packet_Abort;
263 
264 typedef struct {
265 	PacketHeader header;
266 	uint16 reason;  /* Actually NetplayResetReason */
267 	uint16 padding0;
268 } Packet_Reset;
269 
270 
271 #ifndef PACKET_H_STANDALONE
272 void Packet_delete(Packet *packet);
273 Packet_Init *Packet_Init_create(void);
274 Packet_Ping *Packet_Ping_create(uint32 id);
275 Packet_Ack *Packet_Ack_create(uint32 id);
276 Packet_Ready *Packet_Ready_create(void);
277 Packet_Handshake0 *Packet_Handshake0_create(void);
278 Packet_Handshake1 *Packet_Handshake1_create(void);
279 Packet_HandshakeCancel *Packet_HandshakeCancel_create(void);
280 Packet_HandshakeCancelAck *Packet_HandshakeCancelAck_create(void);
281 Packet_SeedRandom *Packet_SeedRandom_create(uint32 seed);
282 Packet_InputDelay *Packet_InputDelay_create(uint32 delay);
283 Packet_Fleet *Packet_Fleet_create(NetplaySide side, size_t numShips);
284 Packet_TeamName *Packet_TeamName_create(NetplaySide side, const char *name,
285 		size_t size);
286 Packet_SelectShip *Packet_SelectShip_create(uint16 ship);
287 Packet_BattleInput *Packet_BattleInput_create(uint8 state);
288 Packet_FrameCount *Packet_FrameCount_create(uint32 frameCount);
289 Packet_Checksum *Packet_Checksum_create(uint32 frameNr, uint32 checksum);
290 Packet_Abort *Packet_Abort_create(uint16 reason);
291 Packet_Reset *Packet_Reset_create(uint16 reason);
292 #endif
293 
294 #if defined(__cplusplus)
295 }
296 #endif
297 
298 #endif  /* UQM_SUPERMELEE_NETPLAY_PACKET_H_ */
299 
300