1 // Emacs style mode select   -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: i_net.h 4469 2014-01-03 23:38:29Z dr_sean $
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 // Copyright (C) 2006-2014 by The Odamex Team.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // DESCRIPTION:
20 //	System specific network interface stuff.
21 //
22 //-----------------------------------------------------------------------------
23 
24 
25 #ifndef __I_NET_H__
26 #define __I_NET_H__
27 
28 #include "doomtype.h"
29 #include "huffman.h"
30 
31 #include <string>
32 
33 // Max packet size to send and receive, in bytes
34 #define	MAX_UDP_PACKET 8192
35 
36 #define SERVERPORT  10666
37 #define CLIENTPORT  10667
38 
39 #define PLAYER_FULLBRIGHTFRAME 70
40 
41 #define CHALLENGE 5560020  // challenge
42 #define LAUNCHER_CHALLENGE 777123  // csdl challenge
43 #define VERSION 65	// GhostlyDeath -- this should remain static from now on
44 
45 extern int   localport;
46 extern int   msg_badread;
47 
48 // network message info
49 struct msg_info_t
50 {
51 	int id;
52 	const char *msgName;
53 	const char *msgFormat; // 'b'=byte, 'n'=short, 'N'=long, 's'=string
54 
getNamemsg_info_t55 	const char *getName() { return msgName ? msgName : ""; }
56 };
57 
58 // network messages
59 enum svc_t
60 {
61 	svc_abort,
62 	svc_full,
63 	svc_disconnect,
64 	svc_reserved3,
65 	svc_playerinfo,			// weapons, ammo, maxammo, raisedweapon for local player
66 	svc_moveplayer,			// [byte] [int] [int] [int] [int] [byte]
67 	svc_updatelocalplayer,	// [int] [int] [int] [int] [int]
68 	svc_pingrequest,		// [SL] 2011-05-11 [long:timestamp]
69 	svc_updateping,			// [byte] [byte]
70 	svc_spawnmobj,			//
71 	svc_disconnectclient,
72 	svc_loadmap,
73 	svc_consoleplayer,
74 	svc_mobjspeedangle,
75 	svc_explodemissile,		// [short] - netid
76 	svc_removemobj,
77 	svc_userinfo,
78 	svc_movemobj,			// [short] [byte] [int] [int] [int]
79 	svc_spawnplayer,
80 	svc_damageplayer,
81 	svc_killmobj,
82 	svc_firepistol,			// [byte] - playernum
83 	svc_fireshotgun,		// [byte] - playernum
84 	svc_firessg,			// [byte] - playernum
85 	svc_firechaingun,		// [byte] - playernum
86 	svc_fireweapon,			// [byte]
87 	svc_sector,
88 	svc_print,
89 	svc_mobjinfo,
90 	svc_updatefrags,		// [byte] [short]
91 	svc_teampoints,
92 	svc_activateline,
93 	svc_movingsector,
94 	svc_startsound,
95 	svc_reconnect,
96 	svc_exitlevel,
97 	svc_touchspecial,
98 	svc_changeweapon,
99 	svc_reserved42,
100 	svc_corpse,
101 	svc_missedpacket,
102 	svc_soundorigin,
103 	svc_reserved46,
104 	svc_reserved47,
105 	svc_forceteam,			// [Toke] Allows server to change a clients team setting.
106 	svc_switch,
107 	svc_say,				// [AM] Similar to a broadcast print except we know who said it.
108 	svc_reserved51,
109 	svc_spawnhiddenplayer,	// [denis] when client can't see player
110 	svc_updatedeaths,		// [byte] [short]
111 	svc_ctfevent,			// [Toke - CTF] - [int]
112 	svc_serversettings,		// 55 [Toke] - informs clients of server settings
113 	svc_spectate,			// [Nes] - [byte:state], [short:playernum]
114 	svc_connectclient,
115     svc_midprint,
116 	svc_svgametic,			// [SL] 2011-05-11 - [byte]
117 	svc_timeleft,
118 	svc_inttimeleft,		// [ML] For intermission timer
119 	svc_mobjtranslation,	// [SL] 2011-09-11 - [byte]
120 	svc_fullupdatedone,		// [SL] Inform client the full update is over
121 	svc_railtrail,			// [SL] Draw railgun trail and play sound
122 	svc_readystate,			// [AM] Broadcast ready state to client
123 	svc_playerstate,		// [SL] Health, armor, and weapon of a player
124 	svc_warmupstate,		// [AM] Broadcast warmup state to client
125 	svc_resetmap,			// [AM] Server is resetting the map
126 
127 	// for co-op
128 	svc_mobjstate = 70,
129 	svc_actor_movedir,
130 	svc_actor_target,
131 	svc_actor_tracer,
132 	svc_damagemobj,
133 
134 	// for downloading
135 	svc_wadinfo,			// denis - [ulong:filesize]
136 	svc_wadchunk,			// denis - [ulong:offset], [ushort:len], [byte[]:data]
137 
138 	// netdemos - NullPoint
139 	svc_netdemocap = 100,
140 	svc_netdemostop = 101,
141 	svc_netdemoloadsnap = 102,
142 
143 	svc_vote_update = 150, // [AM] - Send the latest voting state to the client.
144 	svc_maplist = 155, // [AM] - Return a maplist status.
145 	svc_maplist_update = 156, // [AM] - Send the entire maplist to the client in chunks.
146 	svc_maplist_index = 157, // [AM] - Send the current and next map index to the client.
147 
148 	// for compressed packets
149 	svc_compressed = 200,
150 
151 	// for when launcher packets go astray
152 	svc_launcher_challenge = 212,
153 	svc_challenge = 163,
154 	svc_max = 255
155 };
156 
157 // network messages
158 enum clc_t
159 {
160 	clc_abort,
161 	clc_reserved1,
162 	clc_disconnect,
163 	clc_say,
164 	clc_move,			// send cmds
165 	clc_userinfo,		// send userinfo
166 	clc_pingreply,		// [SL] 2011-05-11 - [long: timestamp]
167 	clc_rate,
168 	clc_ack,
169 	clc_rcon,
170 	clc_rcon_password,
171 	clc_changeteam,		// [NightFang] - Change your team [Toke - Teams] Made this actualy work
172 	clc_ctfcommand,
173 	clc_spectate,			// denis - [byte:state]
174 	clc_wantwad,			// denis - string:name, string:hash
175 	clc_kill,				// denis - suicide
176 	clc_cheat,				// denis - god, pumpkins, etc
177     clc_cheatpulse,         // Russell - one off cheats (idkfa, idfa etc)
178 	clc_callvote,			// [AM] - Calling a vote
179 	clc_vote,				// [AM] - Casting a vote
180 	clc_maplist,			// [AM] - Maplist status request.
181 	clc_maplist_update,     // [AM] - Request the entire maplist from the server.
182 	clc_getplayerinfo,
183 	clc_ready,				// [AM] Toggle ready state.
184 	clc_spy,				// [SL] Tell server to send info about this player
185 	clc_privmsg,			// [AM] Targeted chat to a specific player.
186 
187 	// for when launcher packets go astray
188 	clc_launcher_challenge = 212,
189 	clc_challenge = 163,
190 	clc_max = 255
191 };
192 
193 extern msg_info_t clc_info[clc_max];
194 extern msg_info_t svc_info[svc_max];
195 
196 enum svc_compressed_masks
197 {
198 	adaptive_mask = 1,
199 	adaptive_select_mask = 2,
200 	adaptive_record_mask = 4,
201 	minilzo_mask = 8
202 };
203 
204 typedef struct
205 {
206    byte    ip[4];
207    unsigned short  port;
208    unsigned short  pad;
209 } netadr_t;
210 
211 extern  netadr_t  net_from;  // address of who sent the packet
212 
213 
214 class buf_t
215 {
216 public:
217 	byte	*data;
218 	size_t	allocsize, cursize, readpos;
219 	bool	overflowed;  // set to true if the buffer size failed
220 
221     // Buffer seeking flags
222     typedef enum
223     {
224          BT_SSET // From beginning
225         ,BT_SCUR // From current position
226         ,BT_SEND // From end
227     } seek_loc_t;
228 
229 public:
230 
WriteByte(byte b)231 	void WriteByte(byte b)
232 	{
233 		byte *buf = SZ_GetSpace(sizeof(b));
234 
235 		if(!overflowed)
236 		{
237 			*buf = b;
238 		}
239 	}
240 
WriteShort(short s)241 	void WriteShort(short s)
242 	{
243 		byte *buf = SZ_GetSpace(sizeof(s));
244 
245 		if(!overflowed)
246 		{
247 			buf[0] = s&0xff;
248 			buf[1] = s>>8;
249 		}
250 	}
251 
WriteLong(int l)252 	void WriteLong(int l)
253 	{
254 		byte *buf = SZ_GetSpace(sizeof(l));
255 
256 		if(!overflowed)
257 		{
258 			buf[0] = l&0xff;
259 			buf[1] = (l>>8)&0xff;
260 			buf[2] = (l>>16)&0xff;
261 			buf[3] = l>>24;
262 		}
263 	}
264 
WriteString(const char * c)265 	void WriteString(const char *c)
266 	{
267 		if(c && *c)
268 		{
269 			size_t l = strlen(c);
270 			byte *buf = SZ_GetSpace(l + 1);
271 
272 			if(!overflowed)
273 			{
274 				memcpy(buf, c, l + 1);
275 			}
276 		}
277 		else
278 			WriteByte(0);
279 	}
280 
281 	void WriteChunk(const char *c, unsigned l, int startpos = 0)
282 	{
283 		byte *buf = SZ_GetSpace(l);
284 
285 		if(!overflowed)
286 		{
287 			memcpy(buf, c + startpos, l);
288 		}
289 	}
290 
ReadByte()291 	int ReadByte()
292 	{
293 		if(readpos+1 > cursize)
294 		{
295 			overflowed = true;
296 			return -1;
297 		}
298 		return (unsigned char)data[readpos++];
299 	}
300 
NextByte()301 	int NextByte()
302 	{
303 		if(readpos+1 > cursize)
304 		{
305 			overflowed = true;
306 			return -1;
307 		}
308 		return (unsigned char)data[readpos];
309 	}
310 
ReadChunk(size_t size)311 	byte *ReadChunk(size_t size)
312 	{
313 		if(readpos+size > cursize)
314 		{
315 			overflowed = true;
316 			return NULL;
317 		}
318 		size_t oldpos = readpos;
319 		readpos += size;
320 		return data+oldpos;
321 	}
322 
ReadShort()323 	int ReadShort()
324 	{
325 		if(readpos+2 > cursize)
326 		{
327 			overflowed = true;
328 			return -1;
329 		}
330 		size_t oldpos = readpos;
331 		readpos += 2;
332 		return (short)(data[oldpos] + (data[oldpos+1]<<8));
333 	}
334 
ReadLong()335 	int ReadLong()
336 	{
337 		if(readpos+4 > cursize)
338 		{
339 			overflowed = true;
340 			return -1;
341 		}
342 		size_t oldpos = readpos;
343 		readpos += 4;
344 		return data[oldpos] +
345 				(data[oldpos+1]<<8) +
346 				(data[oldpos+2]<<16)+
347 				(data[oldpos+3]<<24);
348 	}
349 
ReadString()350 	const char *ReadString()
351 	{
352 		byte *begin = data + readpos;
353 
354 		while(ReadByte() > 0);
355 
356 		if(overflowed)
357 		{
358 			return "";
359 		}
360 
361 		return (const char *)begin;
362 	}
363 
SetOffset(const size_t & offset,const seek_loc_t & loc)364     size_t SetOffset (const size_t &offset, const seek_loc_t &loc)
365     {
366         switch (loc)
367         {
368             case BT_SSET:
369             {
370                 if (offset > cursize)
371                 {
372                     overflowed = true;
373                     return 0;
374                 }
375 
376                 readpos = offset;
377             }
378             break;
379 
380             case BT_SCUR:
381             {
382                 if (readpos+offset > cursize)
383                 {
384                     overflowed = true;
385                     return 0;
386                 }
387 
388                 readpos += offset;
389             }
390 
391             case BT_SEND:
392             {
393                 if ((int)(readpos-offset) < 0)
394                 {
395                     // lies, an underflow occured
396                     overflowed = true;
397                     return 0;
398                 }
399 
400                 readpos -= offset;
401             }
402         }
403 
404         return readpos;
405     }
406 
BytesLeftToRead()407 	size_t BytesLeftToRead() const
408 	{
409 		return overflowed || cursize < readpos ? 0 : cursize - readpos;
410 	}
411 
BytesRead()412 	size_t BytesRead() const
413 	{
414 		return readpos;
415 	}
416 
ptr()417 	byte *ptr()
418 	{
419 		return data;
420 	}
421 
size()422 	size_t size() const
423 	{
424 		return cursize;
425 	}
426 
maxsize()427 	size_t maxsize() const
428 	{
429 		return allocsize;
430 	}
431 
setcursize(size_t len)432 	void setcursize(size_t len)
433 	{
434 		cursize = len > allocsize ? allocsize : len;
435 	}
436 
clear()437 	void clear()
438 	{
439 		cursize = 0;
440 		readpos = 0;
441 		overflowed = false;
442 	}
443 
444 	void resize(size_t len, bool clearbuf = true)
445 	{
446 		byte *olddata = data;
447 		data = new byte[len];
448 		allocsize = len;
449 
450 		if (!clearbuf)
451 		{
452 			if (cursize < allocsize)
453 			{
454 				memcpy(data, olddata, cursize);
455 			}
456 			else
457 			{
458 				clear();
459 				overflowed = true;
460 				Printf (PRINT_HIGH, "buf_t::resize(): overflow\n");
461 			}
462 		}
463 		else
464 		{
465 			clear();
466 		}
467 
468 		delete[] olddata;
469 	}
470 
SZ_GetSpace(size_t length)471 	byte *SZ_GetSpace(size_t length)
472 	{
473 		if (cursize + length >= allocsize)
474 		{
475 			clear();
476 			overflowed = true;
477 			Printf (PRINT_HIGH, "SZ_GetSpace: overflow\n");
478 		}
479 
480 		byte *ret = data + cursize;
481 		cursize += length;
482 
483 		return ret;
484 	}
485 
486 	buf_t &operator =(const buf_t &other)
487 	{
488 	    // Avoid self-assignment
489 		if (this == &other)
490             return *this;
491 
492 		delete[] data;
493 
494 		data = new byte[other.allocsize];
495 		allocsize = other.allocsize;
496 		cursize = other.cursize;
497 		overflowed = other.overflowed;
498 		readpos = other.readpos;
499 
500 		if(!overflowed)
501 			for(size_t i = 0; i < cursize; i++)
502 				data[i] = other.data[i];
503 
504 		return *this;
505 	}
506 
buf_t()507 	buf_t()
508 		: data(0), allocsize(0), cursize(0), readpos(0), overflowed(false)
509 	{
510 	}
buf_t(size_t len)511 	buf_t(size_t len)
512 		: data(new byte[len]), allocsize(len), cursize(0), readpos(0), overflowed(false)
513 	{
514 	}
buf_t(const buf_t & other)515 	buf_t(const buf_t &other)
516 		: data(new byte[other.allocsize]), allocsize(other.allocsize), cursize(other.cursize), readpos(other.readpos), overflowed(other.overflowed)
517 
518 	{
519 		if(!overflowed)
520 			for(size_t i = 0; i < cursize; i++)
521 				data[i] = other.data[i];
522 	}
~buf_t()523 	~buf_t()
524 	{
525 		delete[] data;
526 		data = NULL;
527 	}
528 };
529 
530 extern buf_t net_message;
531 
532 void CloseNetwork (void);
533 void InitNetCommon(void);
534 void I_SetPort(netadr_t &addr, int port);
535 bool NetWaitOrTimeout(size_t ms);
536 
537 char *NET_AdrToString (netadr_t a);
538 bool NET_StringToAdr (const char *s, netadr_t *a);
539 bool NET_CompareAdr (netadr_t a, netadr_t b);
540 int  NET_GetPacket (void);
541 void NET_SendPacket (buf_t &buf, netadr_t &to);
542 std::string NET_GetLocalAddress (void);
543 
544 void SZ_Clear (buf_t *buf);
545 void SZ_Write (buf_t *b, const void *data, int length);
546 void SZ_Write (buf_t *b, const byte *data, int startpos, int length);
547 
548 void MSG_WriteByte (buf_t *b, byte c);
549 void MSG_WriteMarker (buf_t *b, svc_t c);
550 void MSG_WriteMarker (buf_t *b, clc_t c);
551 void MSG_WriteShort (buf_t *b, short c);
552 void MSG_WriteLong (buf_t *b, int c);
553 void MSG_WriteBool(buf_t *b, bool);
554 void MSG_WriteFloat(buf_t *b, float);
555 void MSG_WriteString (buf_t *b, const char *s);
556 void MSG_WriteHexString(buf_t *b, const char *s);
557 void MSG_WriteChunk (buf_t *b, const void *p, unsigned l);
558 
559 int MSG_BytesLeft(void);
560 int MSG_NextByte (void);
561 
562 int MSG_ReadByte (void);
563 void *MSG_ReadChunk (const size_t &size);
564 int MSG_ReadShort (void);
565 int MSG_ReadLong (void);
566 bool MSG_ReadBool(void);
567 float MSG_ReadFloat(void);
568 const char *MSG_ReadString (void);
569 
570 size_t MSG_SetOffset (const size_t &offset, const buf_t::seek_loc_t &loc);
571 
572 bool MSG_DecompressMinilzo ();
573 bool MSG_CompressMinilzo (buf_t &buf, size_t start_offset, size_t write_gap);
574 
575 bool MSG_DecompressAdaptive (huffman &huff);
576 bool MSG_CompressAdaptive (huffman &huff, buf_t &buf, size_t start_offset, size_t write_gap);
577 
578 #endif
579 
580 
581 
582