Odamex
Setting the Standard in Multiplayer Doom
common/i_net.h
Go to the documentation of this file.
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends