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