1 //       _________ __                 __
2 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
3 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
4 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
5 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
6 //             \/                  \/          \//_____/            \/
7 //  ______________________                           ______________________
8 //                        T H E   W A R   B E G I N S
9 //         Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name net_message.h - The network message header file. */
12 //
13 //      (c) Copyright 2013 by Joris Dauphin
14 //
15 //      This program is free software; you can redistribute it and/or modify
16 //      it under the terms of the GNU General Public License as published by
17 //      the Free Software Foundation; only version 2 of the License.
18 //
19 //      This program is distributed in the hope that it will be useful,
20 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //      GNU General Public License for more details.
23 //
24 //      You should have received a copy of the GNU General Public License
25 //      along with this program; if not, write to the Free Software
26 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 //      02111-1307, USA.
28 
29 #ifndef NET_MESSAGE_H
30 #define NET_MESSAGE_H
31 
32 //@{
33 
34 #include <stdint.h>
35 #include <vector>
36 
37 /*----------------------------------------------------------------------------
38 --  Declarations
39 ----------------------------------------------------------------------------*/
40 
41 /**
42  * Number of bytes in the name of a network player,
43  * including the terminating null character.
44  */
45 #define NetPlayerNameSize 16
46 
47 #define MaxNetworkCommands 9  /// Max Commands In A Packet
48 
49 /**
50 **  Network systems active in current game.
51 */
52 class CNetworkHost
53 {
54 public:
CNetworkHost()55 	CNetworkHost() { Clear(); }
56 	size_t Serialize(unsigned char *buf) const;
57 	size_t Deserialize(const unsigned char *buf);
58 	void Clear();
Size()59 	static size_t Size() { return 4 + 2 + 2 + NetPlayerNameSize; }
60 
61 	void SetName(const char *name);
62 
63 	uint32_t Host;         /// Host address
64 	uint16_t Port;         /// Port on host
65 	uint16_t PlyNr;        /// Player number
66 	char PlyName[NetPlayerNameSize];  /// Name of player
67 };
68 
69 /**
70 **  Multiplayer game setup menu state
71 */
72 class CServerSetup
73 {
74 public:
CServerSetup()75 	CServerSetup() { Clear(); }
76 	size_t Serialize(unsigned char *p) const;
77 	size_t Deserialize(const unsigned char *p);
Size()78 	static size_t Size() { return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 * PlayerMax + 1 * PlayerMax + 1 * PlayerMax; }
79 	void Clear();
80 
81 	bool operator == (const CServerSetup &rhs) const;
82 	bool operator != (const CServerSetup &rhs) const { return !(*this == rhs); }
83 public:
84 	uint8_t ResourcesOption;       /// Resources option
85 	uint8_t UnitsOption;           /// Unit # option
86 	uint8_t FogOfWar;              /// Fog of war option
87 	uint8_t Inside;                /// Inside option
88 	uint8_t RevealMap;             /// Reveal all the map
89 	uint8_t TilesetSelection;      /// Tileset select option
90 	uint8_t GameTypeOption;        /// Game type option
91 	uint8_t Difficulty;            /// Difficulty option
92 	uint8_t MapRichness;           /// Map richness option
93 	uint8_t Opponents;             /// Number of AI opponents
94 	uint8_t CompOpt[PlayerMax];    /// Free slot option selection  {"Available", "Computer", "Closed" }
95 	uint8_t Ready[PlayerMax];      /// Client ready state
96 	uint8_t Race[PlayerMax];       /// Client race selection
97 	// Fill in here...
98 };
99 
100 /**
101 **  Network init config message subtypes (menu state machine).
102 */
103 enum _ic_message_subtype_ {
104 	ICMHello,               /// Client Request
105 	ICMConfig,              /// Setup message configure clients
106 
107 	ICMEngineMismatch,      /// Stratagus engine version doesn't match
108 	ICMLuaFilesMismatch,    /// Network protocol version doesn't match
109 	ICMEngineConfMismatch,  /// UNUSED:Engine configuration isn't identical
110 	ICMMapUidMismatch,      /// MAP UID doesn't match
111 
112 	ICMGameFull,            /// No player slots available
113 	ICMWelcome,             /// Acknowledge for new client connections
114 
115 	ICMWaiting,             /// Client has received Welcome and is waiting for Map/State
116 	ICMMap,                 /// MapInfo (and Mapinfo Ack)
117 	ICMState,               /// StateInfo
118 	ICMResync,              /// Ack StateInfo change
119 
120 	ICMServerQuit,          /// Server has quit game
121 	ICMGoodBye,             /// Client wants to leave game
122 	ICMSeeYou,              /// Client has left game
123 
124 	ICMGo,                  /// Client is ready to run
125 
126 	ICMAYT,                 /// Server asks are you there
127 	ICMIAH                  /// Client answers I am here
128 };
129 
130 class CInitMessage_Header
131 {
132 public:
CInitMessage_Header()133 	CInitMessage_Header() {}
CInitMessage_Header(unsigned char type,unsigned char subtype)134 	CInitMessage_Header(unsigned char type, unsigned char subtype) :
135 		type(type),
136 		subtype(subtype)
137 	{}
138 
GetType()139 	unsigned char GetType() const { return type; }
GetSubType()140 	unsigned char GetSubType() const { return subtype; }
141 
142 	size_t Serialize(unsigned char *p) const;
143 	size_t Deserialize(const unsigned char *p);
Size()144 	static size_t Size() { return 2; }
145 private:
146 	unsigned char type;
147 	unsigned char subtype;
148 };
149 
150 class CInitMessage_Hello
151 {
152 public:
CInitMessage_Hello()153 	CInitMessage_Hello() {}
154 	explicit CInitMessage_Hello(const char *name);
GetHeader()155 	const CInitMessage_Header &GetHeader() const { return header; }
156 	const unsigned char *Serialize() const;
157 	void Deserialize(const unsigned char *p);
Size()158 	static size_t Size() { return CInitMessage_Header::Size() + NetPlayerNameSize + 2 * 4; }
159 private:
160 	CInitMessage_Header header;
161 public:
162 	char PlyName[NetPlayerNameSize];  /// Name of player
163 	int32_t Stratagus;  /// Stratagus engine version
164 	uint32_t Version;   /// Lua files version
165 };
166 
167 class CInitMessage_Config
168 {
169 public:
170 	CInitMessage_Config();
GetHeader()171 	const CInitMessage_Header &GetHeader() const { return header; }
172 	const unsigned char *Serialize() const;
173 	void Deserialize(const unsigned char *p);
Size()174 	static size_t Size() { return CInitMessage_Header::Size() + 4 + PlayerMax * CNetworkHost::Size(); }
175 private:
176 	CInitMessage_Header header;
177 public:
178 	uint8_t clientIndex; /// index of receiver in hosts[]
179 	uint8_t hostsCount;  /// Number of hosts
180 	CNetworkHost hosts[PlayerMax]; /// Participant information
181 };
182 
183 class CInitMessage_EngineMismatch
184 {
185 public:
186 	CInitMessage_EngineMismatch();
GetHeader()187 	const CInitMessage_Header &GetHeader() const { return header; }
188 	const unsigned char *Serialize() const;
189 	void Deserialize(const unsigned char *p);
Size()190 	static size_t Size() { return CInitMessage_Header::Size() + 4; }
191 private:
192 	CInitMessage_Header header;
193 public:
194 	int32_t Stratagus;  /// Stratagus engine version
195 };
196 
197 class CInitMessage_LuaFilesMismatch
198 {
199 public:
200 	CInitMessage_LuaFilesMismatch();
GetHeader()201 	const CInitMessage_Header &GetHeader() const { return header; }
202 	const unsigned char *Serialize() const;
203 	void Deserialize(const unsigned char *p);
Size()204 	static size_t Size() { return CInitMessage_Header::Size() + 4; }
205 private:
206 	CInitMessage_Header header;
207 public:
208 	uint32_t Version;  /// Lua files version
209 };
210 
211 class CInitMessage_Welcome
212 {
213 public:
214 	CInitMessage_Welcome();
GetHeader()215 	const CInitMessage_Header &GetHeader() const { return header; }
216 	const unsigned char *Serialize() const;
217 	void Deserialize(const unsigned char *p);
Size()218 	static size_t Size() { return CInitMessage_Header::Size() + PlayerMax * CNetworkHost::Size() + 2 * 4; }
219 private:
220 	CInitMessage_Header header;
221 public:
222 	CNetworkHost hosts[PlayerMax]; /// Participants information
223 	int32_t Lag;                   /// Lag time
224 	int32_t gameCyclesPerUpdate;   /// Update frequency
225 };
226 
227 class CInitMessage_Map
228 {
229 public:
CInitMessage_Map()230 	CInitMessage_Map() {}
231 	CInitMessage_Map(const char *path, uint32_t mapUID);
GetHeader()232 	const CInitMessage_Header &GetHeader() const { return header; }
233 	const unsigned char *Serialize() const;
234 	void Deserialize(const unsigned char *p);
Size()235 	static size_t Size() { return CInitMessage_Header::Size() + 256 + 4; }
236 private:
237 	CInitMessage_Header header;
238 public:
239 	char MapPath[256];
240 	uint32_t MapUID;  /// UID of map to play.
241 };
242 
243 class CInitMessage_State
244 {
245 public:
CInitMessage_State()246 	CInitMessage_State() {}
247 	CInitMessage_State(int type, const CServerSetup &data);
GetHeader()248 	const CInitMessage_Header &GetHeader() const { return header; }
249 	const unsigned char *Serialize() const;
250 	void Deserialize(const unsigned char *p);
Size()251 	static size_t Size() { return CInitMessage_Header::Size() + CServerSetup::Size(); }
252 private:
253 	CInitMessage_Header header;
254 public:
255 	CServerSetup State;  /// Server Setup State information
256 };
257 
258 class CInitMessage_Resync
259 {
260 public:
261 	CInitMessage_Resync();
GetHeader()262 	const CInitMessage_Header &GetHeader() const { return header; }
263 	const unsigned char *Serialize() const;
264 	void Deserialize(const unsigned char *p);
Size()265 	static size_t Size() { return CInitMessage_Header::Size() + CNetworkHost::Size() * PlayerMax; }
266 private:
267 	CInitMessage_Header header;
268 public:
269 	CNetworkHost hosts[PlayerMax]; /// Participant information
270 };
271 
272 /**
273 **  Network message types.
274 **
275 **  @todo cleanup the message types.
276 */
277 enum _message_type_ {
278 	MessageNone,                   /// When Nothing Is Happening
279 	MessageInit_FromClient,        /// Start connection
280 	MessageInit_FromServer,        /// Connection reply
281 
282 	MessageSync,                   /// Heart beat
283 	MessageSelection,              /// Update a Selection from Team Player
284 	MessageQuit,                   /// Quit game
285 	MessageResend,                 /// Resend message
286 
287 	MessageChat,                   /// Chat message
288 
289 	MessageCommandStop,            /// Unit command stop
290 	MessageCommandStand,           /// Unit command stand ground
291 	MessageCommandDefend,          /// Unit command defend
292 	MessageCommandFollow,          /// Unit command follow
293 	MessageCommandMove,            /// Unit command move
294 	MessageCommandRepair,          /// Unit command repair
295 	MessageCommandAutoRepair,      /// Unit command autorepair
296 	MessageCommandAttack,          /// Unit command attack
297 	MessageCommandGround,          /// Unit command attack ground
298 	MessageCommandPatrol,          /// Unit command patrol
299 	MessageCommandBoard,           /// Unit command board
300 	MessageCommandUnload,          /// Unit command unload
301 	MessageCommandBuild,           /// Unit command build building
302 	MessageCommandExplore,         /// Unit command explore
303 	MessageCommandDismiss,         /// Unit command dismiss unit
304 	MessageCommandResourceLoc,     /// Unit command resource location
305 	MessageCommandResource,        /// Unit command resource
306 	MessageCommandReturn,          /// Unit command return goods
307 	MessageCommandTrain,           /// Unit command train
308 	MessageCommandCancelTrain,     /// Unit command cancel training
309 	MessageCommandUpgrade,         /// Unit command upgrade
310 	MessageCommandCancelUpgrade,   /// Unit command cancel upgrade
311 	MessageCommandResearch,        /// Unit command research
312 	MessageCommandCancelResearch,  /// Unit command cancel research
313 
314 	MessageExtendedCommand,        /// Command is the next byte
315 
316 	// ATTN: __MUST__ be last due to spellid encoding!!!
317 	MessageCommandSpellCast        /// Unit command spell cast
318 };
319 
320 /**
321 **  Network extended message types.
322 */
323 enum _extended_message_type_ {
324 	ExtendedMessageDiplomacy,			/// Change diplomacy
325 	ExtendedMessageSharedVision,		/// Change shared vision
326 	ExtendedMessageAutoTargetingDB,		/// Change Auto targetting algorithm. Used for debug purposes
327 	ExtendedMessageFieldOfViewDB,		/// Change field of view type (shadow casting or radial). Used for debug purposes
328 	ExtendedMessageMapFieldsOpacityDB,	/// Change opaque flag for forest, rocks or walls. Used for debug purposes
329 	ExtendedMessageRevealMapDB,			/// Change map reveal mode. Used for debug purposes
330 	ExtendedMessageFogOfWarDB			/// Enable/Disable fog of war. Used for debug purposes
331 };
332 
333 /**
334 **  Network command message.
335 */
336 class CNetworkCommand
337 {
338 public:
CNetworkCommand()339 	CNetworkCommand() : Unit(0), X(0), Y(0), Dest(0) {}
Clear()340 	void Clear() { this->Unit = this->X = this->Y = this->Dest = 0; }
341 
342 	size_t Serialize(unsigned char *buf) const;
343 	size_t Deserialize(const unsigned char *buf);
Size()344 	static size_t Size() { return 2 + 2 + 2 + 2; }
345 
346 public:
347 	uint16_t Unit;         /// Command for unit
348 	uint16_t X;            /// Map position X
349 	uint16_t Y;            /// Map position Y
350 	uint16_t Dest;         /// Destination unit
351 };
352 
353 /**
354 **  Extended network command message.
355 */
356 class CNetworkExtendedCommand
357 {
358 public:
CNetworkExtendedCommand()359 	CNetworkExtendedCommand() : ExtendedType(0), Arg1(0), Arg2(0), Arg3(0), Arg4(0) {}
360 
361 	size_t Serialize(unsigned char *buf) const;
362 	size_t Deserialize(const unsigned char *buf);
Size()363 	static size_t Size() { return 1 + 1 + 2 + 2 + 2; }
364 
365 	uint8_t  ExtendedType;  /// Extended network command type
366 	uint8_t  Arg1;          /// Argument 1
367 	uint16_t Arg2;          /// Argument 2
368 	uint16_t Arg3;          /// Argument 3
369 	uint16_t Arg4;          /// Argument 4
370 };
371 
372 /**
373 **  Network chat message.
374 */
375 class CNetworkChat
376 {
377 public:
378 	size_t Serialize(unsigned char *buf) const;
379 	size_t Deserialize(const unsigned char *buf);
380 	size_t Size() const;
381 
382 public:
383 	std::string Text;  /// Message bytes
384 };
385 
386 /**
387 **  Network sync message.
388 */
389 class CNetworkCommandSync
390 {
391 public:
CNetworkCommandSync()392 	CNetworkCommandSync() : syncSeed(0), syncHash(0) {}
393 	size_t Serialize(unsigned char *buf) const;
394 	size_t Deserialize(const unsigned char *buf);
Size()395 	static size_t Size() { return 4 + 4; };
396 
397 public:
398 	uint32_t syncSeed;
399 	uint32_t syncHash;
400 };
401 
402 /**
403 **  Network quit message.
404 */
405 class CNetworkCommandQuit
406 {
407 public:
CNetworkCommandQuit()408 	CNetworkCommandQuit() : player(0) {}
409 	size_t Serialize(unsigned char *buf) const;
410 	size_t Deserialize(const unsigned char *buf);
Size()411 	static size_t Size() { return 2; };
412 
413 public:
414 	uint16_t player;
415 };
416 
417 /**
418 **  Network Selection Update
419 */
420 class CNetworkSelection
421 {
422 public:
CNetworkSelection()423 	CNetworkSelection() : player(0) {}
424 
425 	size_t Serialize(unsigned char *buf) const;
426 	size_t Deserialize(const unsigned char *buf);
427 	size_t Size() const;
428 
429 public:
430 	uint16_t player;
431 	std::vector<uint16_t> Units;  /// Selection Units
432 };
433 
434 /**
435 **  Network packet header.
436 **
437 **  Header for the packet.
438 */
439 class CNetworkPacketHeader
440 {
441 public:
CNetworkPacketHeader()442 	CNetworkPacketHeader()
443 	{
444 		Cycle = 0;
445 		memset(Type, 0, sizeof(Type));
446 		OrigPlayer = 255;
447 	}
448 
449 	size_t Serialize(unsigned char *buf) const;
450 	size_t Deserialize(const unsigned char *buf);
Size()451 	static size_t Size() { return 1 + 1 + 1 * MaxNetworkCommands; }
452 
453 	uint8_t Type[MaxNetworkCommands];  /// Commands in packet
454 	uint8_t Cycle;                     /// Destination game cycle
455 	uint8_t OrigPlayer;                /// Host address
456 };
457 
458 /**
459 **  Network packet.
460 **
461 **  This is sent over the network.
462 */
463 class CNetworkPacket
464 {
465 public:
466 	size_t Serialize(unsigned char *buf, int numcommands) const;
467 	void Deserialize(const unsigned char *buf, unsigned int len, int *numcommands);
468 	size_t Size(int numcommands) const;
469 
470 	CNetworkPacketHeader Header;  /// Packet Header Info
471 	std::vector<unsigned char> Command[MaxNetworkCommands];
472 };
473 
474 //@}
475 
476 #endif // !NET_MESSAGE_H
477