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