|
Odamex
Setting the Standard in Multiplayer Doom
|
00001 // Emacs style mode select -*- C++ -*- 00002 //----------------------------------------------------------------------------- 00003 // 00004 // $Id: i_net.h 2130 2011-03-05 06:12:11Z russellrice $ 00005 // 00006 // Copyright (C) 1993-1996 by id Software, Inc. 00007 // Copyright (C) 2006-2010 by The Odamex Team. 00008 // 00009 // This program is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // This program is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // DESCRIPTION: 00020 // System specific network interface stuff. 00021 // 00022 //----------------------------------------------------------------------------- 00023 00024 00025 #ifndef __I_NET_H__ 00026 #define __I_NET_H__ 00027 00028 #include "doomtype.h" 00029 #include "huffman.h" 00030 00031 #include <string> 00032 00033 #define MAX_UDP_PACKET 8192 00034 00035 #define SERVERPORT 10666 00036 #define CLIENTPORT 10667 00037 00038 #define PLAYER_FULLBRIGHTFRAME 70 00039 00040 #define CHALLENGE 5560020 // challenge 00041 #define LAUNCHER_CHALLENGE 777123 // csdl challenge 00042 #define VERSION 65 // GhostlyDeath -- this should remain static from now on 00043 00044 extern int localport; 00045 extern int msg_badread; 00046 00047 // network message info 00048 struct msg_info_t 00049 { 00050 int id; 00051 const char *msgName; 00052 const char *msgFormat; // 'b'=byte, 'n'=short, 'N'=long, 's'=string 00053 00054 const char *getName() { return msgName ? msgName : ""; } 00055 }; 00056 00057 // network messages 00058 enum svc_t 00059 { 00060 svc_abort, 00061 svc_full, 00062 svc_disconnect, 00063 svc_reserved3, 00064 svc_playerinfo, // weapons, ammo, maxammo, raisedweapon for local player 00065 svc_moveplayer, // [byte] [int] [int] [int] [int] [byte] 00066 svc_updatelocalplayer, // [int] [int] [int] [int] [int] 00067 svc_svgametic, // [int] 00068 svc_updateping, // [byte] [byte] 00069 svc_spawnmobj, // 00070 svc_disconnectclient, 00071 svc_loadmap, 00072 svc_consoleplayer, 00073 svc_mobjspeedangle, 00074 svc_explodemissile, // [short] - netid 00075 svc_removemobj, 00076 svc_userinfo, 00077 svc_movemobj, // [short] [byte] [int] [int] [int] 00078 svc_spawnplayer, 00079 svc_damageplayer, 00080 svc_killmobj, 00081 svc_firepistol, // [byte] - playernum 00082 svc_fireshotgun, // [byte] - playernum 00083 svc_firessg, // [byte] - playernum 00084 svc_firechaingun, // [byte] - playernum 00085 svc_fireweapon, // [byte] 00086 svc_sector, 00087 svc_print, 00088 svc_mobjinfo, 00089 svc_updatefrags, // [byte] [short] 00090 svc_teampoints, 00091 svc_activateline, 00092 svc_movingsector, 00093 svc_startsound, 00094 svc_reconnect, 00095 svc_exitlevel, 00096 svc_touchspecial, 00097 svc_changeweapon, 00098 svc_reserved42, 00099 svc_corpse, 00100 svc_missedpacket, 00101 svc_soundorigin, 00102 svc_reserved46, 00103 svc_reserved47, 00104 svc_forceteam, // [Toke] Allows server to change a clients team setting. 00105 svc_switch, 00106 svc_reserved50, 00107 svc_reserved51, 00108 svc_spawnhiddenplayer, // [denis] when client can't see player 00109 svc_updatedeaths, // [byte] [short] 00110 svc_ctfevent, // [Toke - CTF] - [int] 00111 svc_serversettings, // 55 [Toke] - informs clients of server settings 00112 svc_spectate, // [Nes] - [byte:state], [short:playernum] 00113 svc_connectclient, 00114 svc_midprint, 00115 00116 // for co-op 00117 svc_mobjstate = 70, 00118 svc_actor_movedir, 00119 svc_actor_target, 00120 svc_actor_tracer, 00121 svc_damagemobj, 00122 00123 // for downloading 00124 svc_wadinfo, // denis - [ulong:filesize] 00125 svc_wadchunk, // denis - [ulong:offset], [ushort:len], [byte[]:data] 00126 00127 // for compressed packets 00128 svc_compressed = 200, 00129 00130 // for when launcher packets go astray 00131 svc_launcher_challenge = 212, 00132 svc_challenge = 163, 00133 svc_max = 255 00134 }; 00135 00136 // network messages 00137 enum clc_t 00138 { 00139 clc_abort, 00140 clc_reserved1, 00141 clc_disconnect, 00142 clc_say, 00143 clc_move, // send cmds 00144 clc_userinfo, // send userinfo 00145 clc_svgametic, 00146 clc_rate, 00147 clc_ack, 00148 clc_rcon, 00149 clc_rcon_password, 00150 clc_changeteam, // [NightFang] - Change your team [Toke - Teams] Made this actualy work 00151 clc_ctfcommand, 00152 clc_spectate, // denis - [byte:state] 00153 clc_wantwad, // denis - string:name, string:hash 00154 clc_kill, // denis - suicide 00155 clc_cheat, // denis - god, pumpkins, etc 00156 clc_cheatpulse, // Russell - one off cheats (idkfa, idfa etc) 00157 00158 // for when launcher packets go astray 00159 clc_launcher_challenge = 212, 00160 clc_challenge = 163, 00161 clc_max = 255 00162 }; 00163 00164 extern msg_info_t clc_info[clc_max]; 00165 extern msg_info_t svc_info[svc_max]; 00166 00167 enum svc_compressed_masks 00168 { 00169 adaptive_mask = 1, 00170 adaptive_select_mask = 2, 00171 adaptive_record_mask = 4, 00172 minilzo_mask = 8 00173 }; 00174 00175 typedef struct 00176 { 00177 byte ip[4]; 00178 unsigned short port; 00179 unsigned short pad; 00180 } netadr_t; 00181 00182 extern netadr_t net_from; // address of who sent the packet 00183 00184 00185 class buf_t 00186 { 00187 public: 00188 byte *data; 00189 size_t allocsize, cursize, readpos; 00190 bool overflowed; // set to true if the buffer size failed 00191 00192 public: 00193 00194 void WriteByte(byte b) 00195 { 00196 byte *buf = SZ_GetSpace(sizeof(b)); 00197 00198 if(!overflowed) 00199 { 00200 *buf = b; 00201 } 00202 } 00203 00204 void WriteShort(short s) 00205 { 00206 byte *buf = SZ_GetSpace(sizeof(s)); 00207 00208 if(!overflowed) 00209 { 00210 buf[0] = s&0xff; 00211 buf[1] = s>>8; 00212 } 00213 } 00214 00215 void WriteLong(int l) 00216 { 00217 byte *buf = SZ_GetSpace(sizeof(l)); 00218 00219 if(!overflowed) 00220 { 00221 buf[0] = l&0xff; 00222 buf[1] = (l>>8)&0xff; 00223 buf[2] = (l>>16)&0xff; 00224 buf[3] = l>>24; 00225 } 00226 } 00227 00228 void WriteString(const char *c) 00229 { 00230 if(c && *c) 00231 { 00232 size_t l = strlen(c); 00233 byte *buf = SZ_GetSpace(l + 1); 00234 00235 if(!overflowed) 00236 { 00237 memcpy(buf, c, l + 1); 00238 } 00239 } 00240 else 00241 WriteByte(0); 00242 } 00243 00244 void WriteChunk(const char *c, unsigned l, int startpos = 0) 00245 { 00246 byte *buf = SZ_GetSpace(l); 00247 00248 if(!overflowed) 00249 { 00250 memcpy(buf, c + startpos, l); 00251 } 00252 } 00253 00254 int ReadByte() 00255 { 00256 if(readpos+1 > cursize) 00257 { 00258 overflowed = true; 00259 return -1; 00260 } 00261 return (unsigned char)data[readpos++]; 00262 } 00263 00264 int NextByte() 00265 { 00266 if(readpos+1 > cursize) 00267 { 00268 overflowed = true; 00269 return -1; 00270 } 00271 return (unsigned char)data[readpos]; 00272 } 00273 00274 byte *ReadChunk(size_t size) 00275 { 00276 if(readpos+size > cursize) 00277 { 00278 overflowed = true; 00279 return NULL; 00280 } 00281 size_t oldpos = readpos; 00282 readpos += size; 00283 return data+oldpos; 00284 } 00285 00286 int ReadShort() 00287 { 00288 if(readpos+2 > cursize) 00289 { 00290 overflowed = true; 00291 return -1; 00292 } 00293 size_t oldpos = readpos; 00294 readpos += 2; 00295 return (short)(data[oldpos] + (data[oldpos+1]<<8)); 00296 } 00297 00298 int ReadLong() 00299 { 00300 if(readpos+4 > cursize) 00301 { 00302 overflowed = true; 00303 return -1; 00304 } 00305 size_t oldpos = readpos; 00306 readpos += 4; 00307 return data[oldpos] + 00308 (data[oldpos+1]<<8) + 00309 (data[oldpos+2]<<16)+ 00310 (data[oldpos+3]<<24); 00311 } 00312 00313 const char *ReadString() 00314 { 00315 byte *begin = data + readpos; 00316 00317 while(ReadByte() > 0); 00318 00319 if(overflowed) 00320 { 00321 return ""; 00322 } 00323 00324 return (const char *)begin; 00325 } 00326 00327 size_t BytesLeftToRead() 00328 { 00329 return overflowed || cursize < readpos ? 0 : cursize - readpos; 00330 } 00331 00332 size_t BytesRead() 00333 { 00334 return readpos; 00335 } 00336 00337 byte *ptr() 00338 { 00339 return data; 00340 } 00341 00342 size_t size() 00343 { 00344 return cursize; 00345 } 00346 00347 size_t maxsize() 00348 { 00349 return allocsize; 00350 } 00351 00352 void setcursize(size_t len) 00353 { 00354 cursize = len > allocsize ? allocsize : len; 00355 } 00356 00357 void clear() 00358 { 00359 cursize = 0; 00360 readpos = 0; 00361 overflowed = false; 00362 } 00363 00364 void resize(size_t len) 00365 { 00366 delete[] data; 00367 00368 data = new byte[len]; 00369 allocsize = len; 00370 cursize = 0; 00371 readpos = 0; 00372 overflowed = false; 00373 } 00374 00375 byte *SZ_GetSpace(size_t length) 00376 { 00377 if (cursize + length >= allocsize) 00378 { 00379 clear(); 00380 overflowed = true; 00381 Printf (PRINT_HIGH, "SZ_GetSpace: overflow\n"); 00382 } 00383 00384 byte *ret = data + cursize; 00385 cursize += length; 00386 00387 return ret; 00388 } 00389 00390 buf_t &operator =(const buf_t &other) 00391 { 00392 // Avoid self-assignment 00393 if (this == &other) 00394 return *this; 00395 00396 delete[] data; 00397 00398 data = new byte[other.allocsize]; 00399 allocsize = other.allocsize; 00400 cursize = other.cursize; 00401 overflowed = other.overflowed; 00402 readpos = other.readpos; 00403 00404 if(!overflowed) 00405 for(size_t i = 0; i < cursize; i++) 00406 data[i] = other.data[i]; 00407 00408 return *this; 00409 } 00410 00411 buf_t() 00412 : data(0), allocsize(0), cursize(0), readpos(0), overflowed(false) 00413 { 00414 } 00415 buf_t(size_t len) 00416 : data(new byte[len]), allocsize(len), cursize(0), readpos(0), overflowed(false) 00417 { 00418 } 00419 buf_t(const buf_t &other) 00420 : data(new byte[other.allocsize]), allocsize(other.allocsize), cursize(other.cursize), readpos(other.readpos), overflowed(other.overflowed) 00421 00422 { 00423 if(!overflowed) 00424 for(size_t i = 0; i < cursize; i++) 00425 data[i] = other.data[i]; 00426 } 00427 ~buf_t() 00428 { 00429 delete[] data; 00430 data = NULL; 00431 } 00432 }; 00433 00434 extern buf_t net_message; 00435 00436 void CloseNetwork (void); 00437 void InitNetCommon(void); 00438 void I_SetPort(netadr_t &addr, int port); 00439 bool NetWaitOrTimeout(size_t ms); 00440 00441 char *NET_AdrToString (netadr_t a); 00442 bool NET_StringToAdr (const char *s, netadr_t *a); 00443 bool NET_CompareAdr (netadr_t a, netadr_t b); 00444 int NET_GetPacket (void); 00445 void NET_SendPacket (buf_t &buf, netadr_t &to); 00446 std::string NET_GetLocalAddress (void); 00447 00448 void SZ_Clear (buf_t *buf); 00449 void SZ_Write (buf_t *b, const void *data, int length); 00450 void SZ_Write (buf_t *b, const byte *data, int startpos, int length); 00451 00452 void MSG_WriteByte (buf_t *b, byte c); 00453 void MSG_WriteMarker (buf_t *b, svc_t c); 00454 void MSG_WriteMarker (buf_t *b, clc_t c); 00455 void MSG_WriteShort (buf_t *b, short c); 00456 void MSG_WriteLong (buf_t *b, int c); 00457 void MSG_WriteBool(buf_t *b, bool); 00458 void MSG_WriteFloat(buf_t *b, float); 00459 void MSG_WriteString (buf_t *b, const char *s); 00460 void MSG_WriteChunk (buf_t *b, const void *p, unsigned l); 00461 00462 int MSG_BytesLeft(void); 00463 int MSG_NextByte (void); 00464 00465 int MSG_ReadByte (void); 00466 void *MSG_ReadChunk (const size_t &size); 00467 int MSG_ReadShort (void); 00468 int MSG_ReadLong (void); 00469 bool MSG_ReadBool(void); 00470 float MSG_ReadFloat(void); 00471 const char *MSG_ReadString (void); 00472 00473 bool MSG_DecompressMinilzo (); 00474 bool MSG_CompressMinilzo (buf_t &buf, size_t start_offset, size_t write_gap); 00475 00476 bool MSG_DecompressAdaptive (huffman &huff); 00477 bool MSG_CompressAdaptive (huffman &huff, buf_t &buf, size_t start_offset, size_t write_gap); 00478 00479 #endif 00480 00481 00482