1 // SONIC ROBO BLAST 2 2 //----------------------------------------------------------------------------- 3 // Copyright (C) 1998-2000 by DooM Legacy Team. 4 // Copyright (C) 1999-2020 by Sonic Team Junior. 5 // 6 // This program is free software distributed under the 7 // terms of the GNU General Public License, version 2. 8 // See the 'LICENSE' file for more details. 9 //----------------------------------------------------------------------------- 10 /// \file d_clisrv.h 11 /// \brief high level networking stuff 12 13 #ifndef __D_CLISRV__ 14 #define __D_CLISRV__ 15 16 #include "d_ticcmd.h" 17 #include "d_net.h" 18 #include "d_netcmd.h" 19 #include "d_net.h" 20 #include "tables.h" 21 #include "d_player.h" 22 #include "mserv.h" 23 24 /* 25 The 'packet version' is used to distinguish packet formats. 26 This version is independent of VERSION and SUBVERSION. Different 27 applications may follow different packet versions. 28 */ 29 #define PACKETVERSION 3 30 31 // Network play related stuff. 32 // There is a data struct that stores network 33 // communication related stuff, and another 34 // one that defines the actual packets to 35 // be transmitted. 36 37 // Networking and tick handling related. 38 #define BACKUPTICS 1024 39 #define CLIENTBACKUPTICS 32 40 #define MAXTEXTCMD 256 41 // 42 // Packet structure 43 // 44 typedef enum 45 { 46 PT_NOTHING, // To send a nop through the network. ^_~ 47 PT_SERVERCFG, // Server config used in start game 48 // (must stay 1 for backwards compatibility). 49 // This is a positive response to a CLIENTJOIN request. 50 PT_CLIENTCMD, // Ticcmd of the client. 51 PT_CLIENTMIS, // Same as above with but saying resend from. 52 PT_CLIENT2CMD, // 2 cmds in the packet for splitscreen. 53 PT_CLIENT2MIS, // Same as above with but saying resend from 54 PT_NODEKEEPALIVE, // Same but without ticcmd and consistancy 55 PT_NODEKEEPALIVEMIS, 56 PT_SERVERTICS, // All cmds for the tic. 57 PT_SERVERREFUSE, // Server refuses joiner (reason inside). 58 PT_SERVERSHUTDOWN, 59 PT_CLIENTQUIT, // Client closes the connection. 60 61 PT_ASKINFO, // Anyone can ask info of the server. 62 PT_SERVERINFO, // Send game & server info (gamespy). 63 PT_PLAYERINFO, // Send information for players in game (gamespy). 64 PT_REQUESTFILE, // Client requests a file transfer 65 PT_ASKINFOVIAMS, // Packet from the MS requesting info be sent to new client. 66 // If this ID changes, update masterserver definition. 67 68 PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate! 69 PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead. 70 PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again! 71 72 PT_SENDINGLUAFILE, // Server telling a client Lua needs to open a file 73 PT_ASKLUAFILE, // Client telling the server they don't have the file 74 PT_HASLUAFILE, // Client telling the server they have the file 75 76 // Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility. 77 78 PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL 79 // allows HSendPacket(*, true, *, *) to return false. 80 // In addition, this packet can't occupy all the available slots. 81 82 PT_FILEFRAGMENT = PT_CANFAIL, // A part of a file. 83 PT_FILEACK, 84 PT_FILERECEIVED, 85 86 PT_TEXTCMD, // Extra text commands from the client. 87 PT_TEXTCMD2, // Splitscreen text commands. 88 PT_CLIENTJOIN, // Client wants to join; used in start game. 89 PT_NODETIMEOUT, // Packet sent to self if the connection times out. 90 91 PT_LOGIN, // Login attempt from the client. 92 93 PT_PING, // Packet sent to tell clients the other client's latency to server. 94 NUMPACKETTYPE 95 } packettype_t; 96 97 #ifdef PACKETDROP 98 void Command_Drop(void); 99 void Command_Droprate(void); 100 #endif 101 #ifdef _DEBUG 102 void Command_Numnodes(void); 103 #endif 104 105 #if defined(_MSC_VER) 106 #pragma pack(1) 107 #endif 108 109 // Client to server packet 110 typedef struct 111 { 112 UINT8 client_tic; 113 UINT8 resendfrom; 114 INT16 consistancy; 115 ticcmd_t cmd; 116 } ATTRPACK clientcmd_pak; 117 118 // Splitscreen packet 119 // WARNING: must have the same format of clientcmd_pak, for more easy use 120 typedef struct 121 { 122 UINT8 client_tic; 123 UINT8 resendfrom; 124 INT16 consistancy; 125 ticcmd_t cmd, cmd2; 126 } ATTRPACK client2cmd_pak; 127 128 #ifdef _MSC_VER 129 #pragma warning(disable : 4200) 130 #endif 131 132 // Server to client packet 133 // this packet is too large 134 typedef struct 135 { 136 tic_t starttic; 137 UINT8 numtics; 138 UINT8 numslots; // "Slots filled": Highest player number in use plus one. 139 ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large 140 } ATTRPACK servertics_pak; 141 142 typedef struct 143 { 144 UINT8 version; // Different versions don't work 145 UINT8 subversion; // Contains build version 146 147 // Server launch stuffs 148 UINT8 serverplayer; 149 UINT8 totalslotnum; // "Slots": highest player number in use plus one. 150 151 tic_t gametic; 152 UINT8 clientnode; 153 UINT8 gamestate; 154 155 UINT8 gametype; 156 UINT8 modifiedgame; 157 158 char server_context[8]; // Unique context id, generated at server startup. 159 } ATTRPACK serverconfig_pak; 160 161 typedef struct 162 { 163 UINT8 fileid; 164 UINT32 filesize; 165 UINT8 iteration; 166 UINT32 position; 167 UINT16 size; 168 UINT8 data[0]; // Size is variable using hardware_MAXPACKETLENGTH 169 } ATTRPACK filetx_pak; 170 171 typedef struct 172 { 173 UINT32 start; 174 UINT32 acks; 175 } ATTRPACK fileacksegment_t; 176 177 typedef struct 178 { 179 UINT8 fileid; 180 UINT8 iteration; 181 UINT8 numsegments; 182 fileacksegment_t segments[0]; 183 } ATTRPACK fileack_pak; 184 185 #ifdef _MSC_VER 186 #pragma warning(default : 4200) 187 #endif 188 189 #define MAXAPPLICATION 16 190 191 typedef struct 192 { 193 UINT8 _255;/* see serverinfo_pak */ 194 UINT8 packetversion; 195 char application[MAXAPPLICATION]; 196 UINT8 version; // Different versions don't work 197 UINT8 subversion; // Contains build version 198 UINT8 localplayers; 199 UINT8 mode; 200 char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; 201 } ATTRPACK clientconfig_pak; 202 203 #define MAXSERVERNAME 32 204 #define MAXFILENEEDED 915 205 // This packet is too large 206 typedef struct 207 { 208 /* 209 In the old packet, 'version' is the first field. Now that field is set 210 to 255 always, so older versions won't be confused with the new 211 versions or vice-versa. 212 */ 213 UINT8 _255; 214 UINT8 packetversion; 215 char application[MAXAPPLICATION]; 216 UINT8 version; 217 UINT8 subversion; 218 UINT8 numberofplayer; 219 UINT8 maxplayer; 220 UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full 221 char gametypename[24]; 222 UINT8 modifiedgame; 223 UINT8 cheatsenabled; 224 UINT8 isdedicated; 225 UINT8 fileneedednum; 226 tic_t time; 227 tic_t leveltime; 228 char servername[MAXSERVERNAME]; 229 char mapname[8]; 230 char maptitle[33]; 231 unsigned char mapmd5[16]; 232 UINT8 actnum; 233 UINT8 iszone; 234 UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) 235 } ATTRPACK serverinfo_pak; 236 237 typedef struct 238 { 239 char reason[255]; 240 } ATTRPACK serverrefuse_pak; 241 242 typedef struct 243 { 244 UINT8 version; 245 tic_t time; // used for ping evaluation 246 } ATTRPACK askinfo_pak; 247 248 typedef struct 249 { 250 char clientaddr[22]; 251 tic_t time; // used for ping evaluation 252 } ATTRPACK msaskinfo_pak; 253 254 // Shorter player information for external use. 255 typedef struct 256 { 257 UINT8 num; 258 char name[MAXPLAYERNAME+1]; 259 UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH 260 UINT8 team; 261 UINT8 skin; 262 UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. 263 UINT32 score; 264 UINT16 timeinserver; // In seconds. 265 } ATTRPACK plrinfo; 266 267 // Shortest player information for join during intermission. 268 typedef struct 269 { 270 char name[MAXPLAYERNAME+1]; 271 UINT8 skin; 272 UINT16 color; 273 UINT32 pflags; 274 UINT32 score; 275 UINT8 ctfteam; 276 } ATTRPACK plrconfig; 277 278 // 279 // Network packet data 280 // 281 typedef struct 282 { 283 UINT32 checksum; 284 UINT8 ack; // If not zero the node asks for acknowledgement, the receiver must resend the ack 285 UINT8 ackreturn; // The return of the ack number 286 287 UINT8 packettype; 288 UINT8 reserved; // Padding 289 union 290 { 291 clientcmd_pak clientpak; // 144 bytes 292 client2cmd_pak client2pak; // 200 bytes 293 servertics_pak serverpak; // 132495 bytes (more around 360, no?) 294 serverconfig_pak servercfg; // 773 bytes 295 UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) 296 filetx_pak filetxpak; // 139 bytes 297 fileack_pak fileack; 298 UINT8 filereceived; 299 clientconfig_pak clientcfg; // 136 bytes 300 UINT8 md5sum[16]; 301 serverinfo_pak serverinfo; // 1024 bytes 302 serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) 303 askinfo_pak askinfo; // 61 bytes 304 msaskinfo_pak msaskinfo; // 22 bytes 305 plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?) 306 plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) 307 UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes 308 } u; // This is needed to pack diff packet types data together 309 } ATTRPACK doomdata_t; 310 311 #if defined(_MSC_VER) 312 #pragma pack() 313 #endif 314 315 #define MAXSERVERLIST (MAXNETNODES-1) 316 typedef struct 317 { 318 SINT8 node; 319 serverinfo_pak info; 320 } serverelem_t; 321 322 extern serverelem_t serverlist[MAXSERVERLIST]; 323 extern UINT32 serverlistcount; 324 extern INT32 mapchangepending; 325 326 // Points inside doomcom 327 extern doomdata_t *netbuffer; 328 329 extern consvar_t cv_showjoinaddress; 330 extern consvar_t cv_playbackspeed; 331 332 #define BASEPACKETSIZE offsetof(doomdata_t, u) 333 #define FILETXHEADER offsetof(filetx_pak, data) 334 #define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0]) 335 336 #define KICK_MSG_GO_AWAY 1 337 #define KICK_MSG_CON_FAIL 2 338 #define KICK_MSG_PLAYER_QUIT 3 339 #define KICK_MSG_TIMEOUT 4 340 #define KICK_MSG_BANNED 5 341 #define KICK_MSG_PING_HIGH 6 342 #define KICK_MSG_CUSTOM_KICK 7 343 #define KICK_MSG_CUSTOM_BAN 8 344 #define KICK_MSG_KEEP_BODY 0x80 345 346 typedef enum 347 { 348 KR_KICK = 1, //Kicked by server 349 KR_PINGLIMIT = 2, //Broke Ping Limit 350 KR_SYNCH = 3, //Synch Failure 351 KR_TIMEOUT = 4, //Connection Timeout 352 KR_BAN = 5, //Banned by server 353 KR_LEAVE = 6, //Quit the game 354 355 } kickreason_t; 356 357 /* the max number of name changes in some time period */ 358 #define MAXNAMECHANGES (5) 359 #define NAMECHANGERATE (60*TICRATE) 360 361 extern boolean server; 362 extern boolean serverrunning; 363 #define client (!server) 364 extern boolean dedicated; // For dedicated server 365 extern UINT16 software_MAXPACKETLENGTH; 366 extern boolean acceptnewnode; 367 extern SINT8 servernode; 368 369 void Command_Ping_f(void); 370 extern tic_t connectiontimeout; 371 extern tic_t jointimeout; 372 extern UINT16 pingmeasurecount; 373 extern UINT32 realpingtable[MAXPLAYERS]; 374 extern UINT32 playerpingtable[MAXPLAYERS]; 375 extern tic_t servermaxping; 376 377 extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; 378 extern consvar_t cv_resynchattempts, cv_blamecfail; 379 extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; 380 381 // Used in d_net, the only dependence 382 tic_t ExpandTics(INT32 low, INT32 node); 383 void D_ClientServerInit(void); 384 385 // Initialise the other field 386 void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)); 387 void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam); 388 void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player 389 void SendKick(UINT8 playernum, UINT8 msg); 390 391 // Create any new ticcmds and broadcast to other players. 392 void NetUpdate(void); 393 394 void SV_StartSinglePlayerServer(void); 395 boolean SV_SpawnServer(void); 396 void SV_StopServer(void); 397 void SV_ResetServer(void); 398 void CL_AddSplitscreenPlayer(void); 399 void CL_RemoveSplitscreenPlayer(void); 400 void CL_Reset(void); 401 void CL_ClearPlayer(INT32 playernum); 402 void CL_QueryServerList(msg_server_t *list); 403 void CL_UpdateServerList(boolean internetsearch, INT32 room); 404 // Is there a game running 405 boolean Playing(void); 406 407 // Broadcasts special packets to other players 408 // to notify of game exit 409 void D_QuitNetGame(void); 410 411 //? How many ticks to run? 412 void TryRunTics(tic_t realtic); 413 414 // extra data for lmps 415 // these functions scare me. they contain magic. 416 /*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum); 417 void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/ 418 419 #ifndef NONET 420 // translate a playername in a player number return -1 if not found and 421 // print a error message in the console 422 SINT8 nametonum(const char *name); 423 #endif 424 425 extern char motd[254], server_context[8]; 426 extern UINT8 playernode[MAXPLAYERS]; 427 428 INT32 D_NumPlayers(void); 429 void D_ResetTiccmds(void); 430 431 tic_t GetLag(INT32 node); 432 UINT8 GetFreeXCmdSize(void); 433 434 void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); 435 436 extern UINT8 hu_redownloadinggamestate; 437 438 extern UINT8 adminpassmd5[16]; 439 extern boolean adminpasswordset; 440 #endif 441