mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
733 lines
22 KiB
C
733 lines
22 KiB
C
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2025 by Kart Krew.
|
|
// Copyright (C) 2020 by Sonic Team Junior.
|
|
// Copyright (C) 2000 by DooM Legacy Team.
|
|
//
|
|
// This program is free software distributed under the
|
|
// terms of the GNU General Public License, version 2.
|
|
// See the 'LICENSE' file for more details.
|
|
//-----------------------------------------------------------------------------
|
|
/// \file d_clisrv.h
|
|
/// \brief high level networking stuff
|
|
|
|
#ifndef __D_CLISRV__
|
|
#define __D_CLISRV__
|
|
|
|
#include "d_ticcmd.h"
|
|
#include "d_net.h"
|
|
#include "d_netcmd.h"
|
|
#include "d_net.h"
|
|
#include "tables.h"
|
|
#include "d_player.h"
|
|
#include "mserv.h"
|
|
|
|
#include "k_pwrlv.h" // PWRLV_NUMTYPES
|
|
#include "p_saveg.h" // NETSAVEGAMESIZE
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
The 'packet version' is used to distinguish packet formats.
|
|
This version is independent of VERSION and SUBVERSION. Different
|
|
applications may follow different packet versions.
|
|
*/
|
|
#define PACKETVERSION 0
|
|
|
|
// Network play related stuff.
|
|
// There is a data struct that stores network
|
|
// communication related stuff, and another
|
|
// one that defines the actual packets to
|
|
// be transmitted.
|
|
|
|
#define HU_MAXMSGLEN 223
|
|
|
|
#define MAXSERVERNAME 32
|
|
#define MAXSERVERCONTACT 1024
|
|
|
|
// Networking and tick handling related.
|
|
#define BACKUPTICS 512 // more than enough for most timeouts....
|
|
#define CLIENTBACKUPTICS 32
|
|
#define MAXTEXTCMD 512
|
|
|
|
// No. of tics your controls can be delayed by.
|
|
|
|
// TODO: Instead of storing a ton of extra cmds for gentlemens' delay,
|
|
// keep them in a linked-list, with timestamps to discard everything that's older than already sent.
|
|
// That will support any amount of lag, and be less wasteful for clients who don't use it.
|
|
// This just works as a quick implementation.
|
|
#define MAXGENTLEMENDELAY TICRATE
|
|
|
|
//
|
|
// Packet structure
|
|
//
|
|
typedef enum
|
|
{
|
|
PT_NOTHING, // To send a nop through the network. ^_~
|
|
PT_SERVERCFG, // Server config used in start game
|
|
// (must stay 1 for backwards compatibility).
|
|
// This is a positive response to a CLIENTJOIN request.
|
|
PT_CLIENTCMD, // Ticcmd of the client.
|
|
PT_CLIENTMIS, // Same as above with but saying resend from.
|
|
PT_CLIENT2CMD, // 2 cmds in the packet for splitscreen.
|
|
PT_CLIENT2MIS, // Same as above with but saying resend from
|
|
PT_NODEKEEPALIVE, // Same but without ticcmd and consistancy
|
|
PT_NODEKEEPALIVEMIS,
|
|
PT_SERVERTICS, // All cmds for the tic.
|
|
PT_SERVERREFUSE, // Server refuses joiner (reason inside).
|
|
PT_SERVERSHUTDOWN,
|
|
PT_CLIENTQUIT, // Client closes the connection.
|
|
|
|
PT_ASKINFO, // Anyone can ask info of the server.
|
|
PT_SERVERINFO, // Send game & server info (gamespy).
|
|
PT_PLAYERINFO, // Send information for players in game (gamespy).
|
|
PT_REQUESTFILE, // Client requests a file transfer
|
|
PT_ASKINFOVIAMS, // Packet from the MS requesting info be sent to new client.
|
|
// If this ID changes, update masterserver definition.
|
|
|
|
PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate!
|
|
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
|
|
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
|
|
|
|
PT_SENDINGLUAFILE, // Server telling a client Lua needs to open a file
|
|
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
|
PT_HASLUAFILE, // Client telling the server they have the file
|
|
|
|
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
|
|
|
// Kart-specific packets
|
|
PT_CLIENT3CMD, // 3P
|
|
PT_CLIENT3MIS,
|
|
PT_CLIENT4CMD, // 4P
|
|
PT_CLIENT4MIS,
|
|
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
|
|
|
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
|
|
// allows HSendPacket(*, true, *, *) to return false.
|
|
// In addition, this packet can't occupy all the available slots.
|
|
|
|
PT_FILEFRAGMENT = PT_CANFAIL, // A part of a file.
|
|
PT_FILEACK,
|
|
PT_FILERECEIVED,
|
|
|
|
PT_TEXTCMD, // Extra text commands from the client.
|
|
PT_TEXTCMD2, // Splitscreen text commands.
|
|
PT_TEXTCMD3, // 3P
|
|
PT_TEXTCMD4, // 4P
|
|
PT_CLIENTJOIN, // Client wants to join; used in start game.
|
|
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
|
|
|
|
PT_TELLFILESNEEDED, // Client, to server: "what other files do I need starting from this number?"
|
|
PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)"
|
|
|
|
PT_LOGIN, // Login attempt from the client.
|
|
|
|
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
|
|
|
PT_CLIENTKEY, // "Here's my public key"
|
|
PT_SERVERCHALLENGE, // "Prove it"
|
|
|
|
PT_CHALLENGEALL, // Prove to the other clients you are who you say you are, sign this random bullshit!
|
|
PT_RESPONSEALL, // OK, here is my signature on that random bullshit
|
|
PT_RESULTSALL, // Here's what everyone responded to PT_CHALLENGEALL with, if this is wrong or you don't receive it disconnect
|
|
|
|
PT_SAY, // "Hey server, please send this chat message to everyone via XD_SAY"
|
|
|
|
PT_REQMAPQUEUE, // Client requesting a roundqueue operation
|
|
|
|
PT_VOICE, // Voice packet for either side
|
|
|
|
NUMPACKETTYPE
|
|
} packettype_t;
|
|
|
|
typedef enum
|
|
{
|
|
SIGN_OK,
|
|
SIGN_BADTIME, // Timestamp differs by too much, suspect reuse of an old challenge.
|
|
SIGN_BADIP // Asked to sign the wrong IP by an external host, suspect reuse of another server's challenge.
|
|
} shouldsign_t;
|
|
|
|
#ifdef PACKETDROP
|
|
void Command_Drop(void);
|
|
void Command_Droprate(void);
|
|
#endif
|
|
void Command_Numnodes(void);
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma pack(1)
|
|
#endif
|
|
|
|
// Client to server packet
|
|
struct clientcmd_pak
|
|
{
|
|
UINT8 client_tic;
|
|
UINT8 resendfrom;
|
|
INT16 consistancy;
|
|
UINT8 wantdelay;
|
|
ticcmd_t cmd;
|
|
} ATTRPACK;
|
|
|
|
// Splitscreen packet
|
|
// WARNING: must have the same format of clientcmd_pak, for more easy use
|
|
struct client2cmd_pak
|
|
{
|
|
UINT8 client_tic;
|
|
UINT8 resendfrom;
|
|
INT16 consistancy;
|
|
UINT8 wantdelay;
|
|
ticcmd_t cmd, cmd2;
|
|
} ATTRPACK;
|
|
|
|
// 3P Splitscreen packet
|
|
// WARNING: must have the same format of clientcmd_pak, for more easy use
|
|
struct client3cmd_pak
|
|
{
|
|
UINT8 client_tic;
|
|
UINT8 resendfrom;
|
|
INT16 consistancy;
|
|
UINT8 wantdelay;
|
|
ticcmd_t cmd, cmd2, cmd3;
|
|
} ATTRPACK;
|
|
|
|
// 4P Splitscreen packet
|
|
// WARNING: must have the same format of clientcmd_pak, for more easy use
|
|
struct client4cmd_pak
|
|
{
|
|
UINT8 client_tic;
|
|
UINT8 resendfrom;
|
|
INT16 consistancy;
|
|
UINT8 wantdelay;
|
|
ticcmd_t cmd, cmd2, cmd3, cmd4;
|
|
} ATTRPACK;
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable : 4200)
|
|
#endif
|
|
|
|
// Server to client packet
|
|
// this packet is too large
|
|
struct servertics_pak
|
|
{
|
|
UINT8 starttic;
|
|
UINT8 numtics;
|
|
UINT8 numslots; // "Slots filled": Highest player number in use plus one.
|
|
ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large
|
|
} ATTRPACK;
|
|
|
|
struct serverconfig_pak
|
|
{
|
|
UINT8 version; // Different versions don't work
|
|
UINT8 subversion; // Contains build version
|
|
|
|
// Server launch stuffs
|
|
UINT8 serverplayer;
|
|
UINT8 totalslotnum; // "Slots": highest player number in use plus one.
|
|
|
|
tic_t gametic;
|
|
UINT8 clientnode;
|
|
UINT8 gamestate;
|
|
|
|
UINT8 gametype;
|
|
UINT8 modifiedgame;
|
|
|
|
char server_context[8]; // Unique context id, generated at server startup.
|
|
|
|
// Discord info (always defined for net compatibility)
|
|
UINT8 maxplayer;
|
|
boolean allownewplayer;
|
|
boolean discordinvites;
|
|
|
|
char server_name[MAXSERVERNAME];
|
|
char server_contact[MAXSERVERCONTACT];
|
|
} ATTRPACK;
|
|
|
|
struct filetx_pak
|
|
{
|
|
UINT8 fileid;
|
|
UINT32 filesize;
|
|
UINT8 iteration;
|
|
UINT32 position;
|
|
UINT16 size;
|
|
UINT8 data[]; // Size is variable using hardware_MAXPACKETLENGTH
|
|
} ATTRPACK;
|
|
|
|
struct fileacksegment_t
|
|
{
|
|
UINT32 start;
|
|
UINT32 acks;
|
|
} ATTRPACK;
|
|
|
|
struct fileack_pak
|
|
{
|
|
UINT8 fileid;
|
|
UINT8 iteration;
|
|
UINT8 numsegments;
|
|
fileacksegment_t segments[];
|
|
} ATTRPACK;
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(default : 4200)
|
|
#endif
|
|
|
|
#define MAXAPPLICATION 16
|
|
|
|
struct player_config_t
|
|
{
|
|
char name[MAXPLAYERNAME+1];
|
|
UINT16 skin;
|
|
UINT16 color;
|
|
INT16 follower;
|
|
UINT16 follower_color;
|
|
UINT8 weapon_prefs;
|
|
UINT8 min_delay;
|
|
uint8_t key[PUBKEYLENGTH];
|
|
UINT16 pwr[PWRLV_NUMTYPES];
|
|
} ATTRPACK;
|
|
|
|
struct clientconfig_pak
|
|
{
|
|
UINT8 _255;/* see serverinfo_pak */
|
|
UINT8 packetversion;
|
|
char application[MAXAPPLICATION];
|
|
UINT8 version; // Different versions don't work
|
|
UINT8 subversion; // Contains build version
|
|
UINT8 localplayers; // number of splitscreen players
|
|
UINT8 mode;
|
|
char _names_outdated[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
|
UINT8 availabilities[MAXAVAILABILITY];
|
|
uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
|
player_config_t player_configs[MAXSPLITSCREENPLAYERS];
|
|
} ATTRPACK;
|
|
|
|
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
|
#define SV_DEDICATED 0x40 // server is dedicated
|
|
#define SV_VOICEENABLED 0x80 // voice_mute is off/voice chat is enabled
|
|
#define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil
|
|
|
|
#define MAXFILENEEDED 915
|
|
#define MAX_MIRROR_LENGTH 256
|
|
// This packet is too large
|
|
struct serverinfo_pak
|
|
{
|
|
/*
|
|
In the old packet, 'version' is the first field. Now that field is set
|
|
to 255 always, so older versions won't be confused with the new
|
|
versions or vice-versa.
|
|
*/
|
|
UINT8 _255;
|
|
UINT8 packetversion;
|
|
char application[MAXAPPLICATION];
|
|
UINT8 version;
|
|
UINT8 subversion;
|
|
UINT8 commit[GIT_SHA_ABBREV];
|
|
UINT8 numberofplayer;
|
|
UINT8 maxplayer;
|
|
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
|
|
char gametypename[24];
|
|
UINT8 modifiedgame;
|
|
UINT8 cheatsenabled;
|
|
UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes
|
|
UINT8 fileneedednum;
|
|
tic_t time;
|
|
tic_t leveltime;
|
|
char servername[MAXSERVERNAME];
|
|
char maptitle[33];
|
|
unsigned char mapmd5[16];
|
|
UINT8 actnum;
|
|
UINT8 iszone;
|
|
char httpsource[MAX_MIRROR_LENGTH]; // HTTP URL to download from, always defined for compatibility
|
|
INT16 avgpwrlv; // Kart avg power level
|
|
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
|
} ATTRPACK;
|
|
|
|
struct serverrefuse_pak
|
|
{
|
|
char reason[255];
|
|
} ATTRPACK;
|
|
|
|
struct askinfo_pak
|
|
{
|
|
UINT8 version;
|
|
tic_t time; // used for ping evaluation
|
|
} ATTRPACK;
|
|
|
|
struct msaskinfo_pak
|
|
{
|
|
char clientaddr[22];
|
|
tic_t time; // used for ping evaluation
|
|
} ATTRPACK;
|
|
|
|
// Shorter player information for external use.
|
|
struct plrinfo
|
|
{
|
|
UINT8 num;
|
|
char name[MAXPLAYERNAME+1];
|
|
UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH
|
|
UINT8 team;
|
|
UINT8 deprecated_skin;
|
|
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
|
|
UINT32 score;
|
|
UINT16 timeinserver; // In seconds.
|
|
} ATTRPACK;
|
|
|
|
struct filesneededconfig_pak
|
|
{
|
|
INT32 first;
|
|
UINT8 num;
|
|
UINT8 more;
|
|
UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
|
} ATTRPACK;
|
|
|
|
struct clientkey_pak
|
|
{
|
|
uint8_t key[MAXSPLITSCREENPLAYERS][PUBKEYLENGTH];
|
|
} ATTRPACK;
|
|
|
|
struct serverchallenge_pak
|
|
{
|
|
uint8_t secret[CHALLENGELENGTH];
|
|
} ATTRPACK;
|
|
|
|
struct challengeall_pak
|
|
{
|
|
uint8_t secret[CHALLENGELENGTH];
|
|
} ATTRPACK;
|
|
|
|
struct responseall_pak
|
|
{
|
|
uint8_t signature[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
|
} ATTRPACK;
|
|
|
|
struct resultsall_pak
|
|
{
|
|
uint8_t signature[MAXPLAYERS][SIGNATURELENGTH];
|
|
} ATTRPACK;
|
|
|
|
struct say_pak
|
|
{
|
|
char message[HU_MAXMSGLEN];
|
|
UINT8 target;
|
|
UINT8 flags;
|
|
UINT8 source;
|
|
} ATTRPACK;
|
|
|
|
struct reqmapqueue_pak
|
|
{
|
|
UINT16 newmapnum;
|
|
UINT16 newgametype;
|
|
UINT8 flags;
|
|
UINT8 source;
|
|
} ATTRPACK;
|
|
|
|
struct netinfo_pak
|
|
{
|
|
UINT32 pingtable[MAXPLAYERS+1];
|
|
UINT32 packetloss[MAXPLAYERS+1];
|
|
UINT32 delay[MAXPLAYERS+1];
|
|
} ATTRPACK;
|
|
|
|
// Sent by both sides. Contains Opus-encoded voice packet
|
|
// flags bitset map (left to right, low to high)
|
|
// | PPPPPTRR | -- P = Player num, T = Terminal, R = Reserved (0)
|
|
// Data following voice header is a single Opus frame
|
|
struct voice_pak
|
|
{
|
|
UINT64 frame;
|
|
UINT8 flags;
|
|
} ATTRPACK;
|
|
|
|
#define VOICE_PAK_FLAGS_PLAYERNUM_BITS 0x1F
|
|
#define VOICE_PAK_FLAGS_TERMINAL_BIT 0x20
|
|
#define VOICE_PAK_FLAGS_RESERVED0_BIT 0x40
|
|
#define VOICE_PAK_FLAGS_RESERVED1_BIT 0x80
|
|
#define VOICE_PAK_FLAGS_RESERVED_BITS (VOICE_PAK_FLAGS_RESERVED0_BIT | VOICE_PAK_FLAGS_RESERVED1_BIT)
|
|
|
|
//
|
|
// Network packet data
|
|
//
|
|
struct doomdata_t
|
|
{
|
|
UINT32 checksum;
|
|
UINT8 ack; // If not zero the node asks for acknowledgement, the receiver must resend the ack
|
|
UINT8 ackreturn; // The return of the ack number
|
|
|
|
UINT8 packettype;
|
|
#ifdef SIGNGAMETRAFFIC
|
|
uint8_t signature[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
|
#endif
|
|
UINT8 reserved; // Padding
|
|
union
|
|
{
|
|
clientcmd_pak clientpak; // 147 bytes
|
|
client2cmd_pak client2pak; // 206 bytes
|
|
client3cmd_pak client3pak; // 264 bytes(?)
|
|
client4cmd_pak client4pak; // 324 bytes(?)
|
|
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
|
serverconfig_pak servercfg; // 773 bytes
|
|
UINT8 textcmd[MAXTEXTCMD+2]; // 66049 bytes (wut??? 64k??? More like 258 bytes...)
|
|
char filetxpak[sizeof (filetx_pak)];// 139 bytes
|
|
char fileack[sizeof (fileack_pak)];
|
|
UINT8 filereceived;
|
|
clientconfig_pak clientcfg; // 650 bytes
|
|
UINT8 md5sum[16];
|
|
serverinfo_pak serverinfo; // 1024 bytes
|
|
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
|
askinfo_pak askinfo; // 61 bytes
|
|
msaskinfo_pak msaskinfo; // 22 bytes
|
|
plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];// 576 bytes(?)
|
|
INT32 filesneedednum; // 4 bytes
|
|
filesneededconfig_pak filesneededcfg; // ??? bytes
|
|
netinfo_pak netinfo; // Don't believe their lies
|
|
clientkey_pak clientkey; // 32 bytes
|
|
serverchallenge_pak serverchallenge; // 256 bytes
|
|
challengeall_pak challengeall; // 256 bytes
|
|
responseall_pak responseall; // 256 bytes
|
|
resultsall_pak resultsall; // 1024 bytes. Also, you really shouldn't trust anything here.
|
|
say_pak say; // I don't care anymore.
|
|
reqmapqueue_pak reqmapqueue; // Formerly XD_REQMAPQUEUE
|
|
voice_pak voice; // Unreliable voice data, variable length
|
|
} u; // This is needed to pack diff packet types data together
|
|
} ATTRPACK;
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma pack()
|
|
#endif
|
|
|
|
#define MAXSERVERLIST (MAXNETNODES-1)
|
|
#define GTCALC_RACE 0
|
|
#define GTCALC_BATTLE 1
|
|
#define GTCALC_CUSTOM 2
|
|
struct serverelem_t
|
|
{
|
|
SINT8 node;
|
|
serverinfo_pak info;
|
|
UINT8 cachedgtcalc;
|
|
};
|
|
|
|
extern serverelem_t serverlist[MAXSERVERLIST];
|
|
extern UINT32 serverlistcount, serverlistultimatecount;
|
|
extern boolean serverlistmode;
|
|
extern INT32 mapchangepending;
|
|
|
|
// Points inside doomcom
|
|
extern doomdata_t *netbuffer;
|
|
extern consvar_t cv_stunserver;
|
|
extern consvar_t cv_httpsource;
|
|
extern consvar_t cv_kicktime;
|
|
|
|
extern consvar_t cv_showjoinaddress;
|
|
extern consvar_t cv_playbackspeed;
|
|
|
|
#define BASEPACKETSIZE offsetof(doomdata_t, u)
|
|
#define FILETXHEADER offsetof(filetx_pak, data)
|
|
#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
|
|
|
|
typedef enum
|
|
{
|
|
KICK_MSG_PLAYER_QUIT = 0, // Player intentionally left
|
|
KICK_MSG_KICKED, // Server kick message w/ no reason
|
|
KICK_MSG_CUSTOM_KICK, // Server kick message w/ reason
|
|
KICK_MSG_VOTE_KICK, // Vote kick message
|
|
KICK_MSG_BANNED, // Ban message w/ no reason
|
|
KICK_MSG_CUSTOM_BAN, // Ban message w/ custom reason
|
|
KICK_MSG_TIMEOUT, // Player's connection timed out
|
|
KICK_MSG_PING_HIGH, // Player hit the ping limit
|
|
KICK_MSG_GRIEF, // Player was detected by antigrief
|
|
KICK_MSG_CON_FAIL, // Player failed to resync game state
|
|
KICK_MSG_SIGFAIL, // Player failed signature check
|
|
KICK_MSG__MAX // Number of unique messages
|
|
} kickmsg_t;
|
|
|
|
typedef enum
|
|
{
|
|
KR_KICK = 1, //Kicked by server
|
|
KR_PINGLIMIT = 2, //Broke Ping Limit
|
|
KR_SYNCH = 3, //Synch Failure
|
|
KR_TIMEOUT = 4, //Connection Timeout
|
|
KR_BAN = 5, //Banned by server
|
|
KR_LEAVE = 6, //Quit the game
|
|
} kickreason_t;
|
|
|
|
/* the max number of name changes in some time period */
|
|
#define MAXNAMECHANGES (5)
|
|
#define NAMECHANGERATE (60*TICRATE)
|
|
|
|
extern boolean server;
|
|
extern boolean serverrunning;
|
|
#define client (!server)
|
|
extern boolean dedicated; // For dedicated server
|
|
extern UINT16 software_MAXPACKETLENGTH;
|
|
extern boolean acceptnewnode;
|
|
extern SINT8 servernode;
|
|
extern char connectedservername[MAXSERVERNAME];
|
|
extern char connectedservercontact[MAXSERVERCONTACT];
|
|
extern UINT32 ourIP;
|
|
extern uint8_t lastReceivedKey[MAXNETNODES][MAXSPLITSCREENPLAYERS][PUBKEYLENGTH];
|
|
extern uint8_t lastSentChallenge[MAXNETNODES][CHALLENGELENGTH];
|
|
extern uint8_t lastChallengeAll[CHALLENGELENGTH];
|
|
extern uint8_t lastReceivedSignature[MAXPLAYERS][SIGNATURELENGTH];
|
|
extern uint8_t knownWhenChallenged[MAXPLAYERS][PUBKEYLENGTH];
|
|
extern boolean expectChallenge;
|
|
|
|
// We give clients a chance to verify each other once per race.
|
|
// When is that challenge sent, and when should clients bail if they don't receive the responses?
|
|
#define CHALLENGEALL_START (TICRATE*5) // Server sends challenges here.
|
|
#define CHALLENGEALL_KICKUNRESPONSIVE (TICRATE*10) // Server kicks players that haven't submitted signatures here.
|
|
#define CHALLENGEALL_SENDRESULTS (TICRATE*15) // Server waits for kicks to process until here. (Failing players shouldn't be in-game when results are received, or clients get spooked.)
|
|
#define CHALLENGEALL_CLIENTCUTOFF (TICRATE*20) // If challenge process hasn't completed by now, clients who were in-game for CHALLENGEALL_START should leave.
|
|
|
|
void Command_Ping_f(void);
|
|
extern tic_t connectiontimeout;
|
|
extern tic_t jointimeout;
|
|
extern UINT16 pingmeasurecount;
|
|
extern UINT32 realpingtable[MAXPLAYERS];
|
|
extern UINT32 playerpingtable[MAXPLAYERS];
|
|
extern UINT32 playerpacketlosstable[MAXPLAYERS];
|
|
extern UINT32 playerdelaytable[MAXPLAYERS];
|
|
extern tic_t servermaxping;
|
|
|
|
extern boolean server_lagless;
|
|
extern consvar_t cv_mindelay;
|
|
|
|
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_maxconnections, cv_joindelay;
|
|
extern consvar_t cv_pingtimeout, cv_blamecfail;
|
|
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
|
|
|
#ifdef VANILLAJOINNEXTROUND
|
|
extern consvar_t cv_joinnextround;
|
|
#endif
|
|
|
|
extern consvar_t cv_discordinvites;
|
|
|
|
extern consvar_t cv_allowguests;
|
|
|
|
extern consvar_t cv_gamestochat;
|
|
|
|
#ifdef DEVELOP
|
|
extern consvar_t cv_badjoin;
|
|
extern consvar_t cv_badtraffic;
|
|
extern consvar_t cv_badresponse;
|
|
extern consvar_t cv_noresponse;
|
|
extern consvar_t cv_nochallenge;
|
|
extern consvar_t cv_badresults;
|
|
extern consvar_t cv_noresults;
|
|
extern consvar_t cv_badtime;
|
|
extern consvar_t cv_badip;
|
|
#endif
|
|
|
|
// Used in d_net, the only dependence
|
|
tic_t ExpandTics(INT32 low, tic_t basetic);
|
|
void D_ClientServerInit(void);
|
|
|
|
void GenerateChallenge(uint8_t *buf);
|
|
shouldsign_t ShouldSignChallenge(uint8_t *message);
|
|
|
|
// Initialise the other field
|
|
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(const UINT8 **p, INT32 playernum));
|
|
void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_t nparam);
|
|
#define SendNetXCmd(id, param, nparam) SendNetXCmdForPlayer(0, id, param, nparam) // Shortcut for P1
|
|
void SendKick(UINT8 playernum, UINT8 msg);
|
|
|
|
// Create any new ticcmds and broadcast to other players.
|
|
void NetKeepAlive(void);
|
|
void NetUpdate(void);
|
|
void NetVoiceUpdate(void);
|
|
|
|
void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame);
|
|
boolean SV_SpawnServer(void);
|
|
void SV_StopServer(void);
|
|
void SV_ResetServer(void);
|
|
|
|
/*--------------------------------------------------
|
|
boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum);
|
|
|
|
Adds a new bot, using a server-sided packet sent to all clients.
|
|
Using regular K_AddBot wherever possible is better, but this is kept
|
|
as a back-up measure if this is the only option.
|
|
|
|
Input Arguments:-
|
|
skin - Skin number that the bot will use.
|
|
difficulty - Difficulty level this bot will use.
|
|
style - Bot style to spawn this bot with, see botStyle_e.
|
|
newplayernum - Pointer to the last valid player slot number.
|
|
Is a pointer so that this function can be called multiple times to add more than one bot.
|
|
|
|
Return:-
|
|
true if a bot can be added via a packet later, otherwise false.
|
|
--------------------------------------------------*/
|
|
|
|
boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
|
|
|
void CL_AddSplitscreenPlayer(void);
|
|
void CL_RemoveSplitscreenPlayer(UINT8 p);
|
|
void CL_Reset(void);
|
|
void CL_ClearPlayer(INT32 playernum);
|
|
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
|
void CL_QueryServerList(msg_server_t *list);
|
|
void CL_UpdateServerList(void);
|
|
void CL_TimeoutServerList(void);
|
|
// Is there a game running
|
|
boolean Playing(void);
|
|
|
|
// Advance client-to-client pubkey verification flow
|
|
void UpdateChallenges(void);
|
|
|
|
// Broadcasts special packets to other players
|
|
// to notify of game exit
|
|
void D_QuitNetGame(void);
|
|
|
|
//? How many ticks to run?
|
|
boolean TryRunTics(tic_t realtic);
|
|
|
|
// extra data for lmps
|
|
// these functions scare me. they contain magic.
|
|
/*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum);
|
|
void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/
|
|
|
|
// translate a playername in a player number return -1 if not found and
|
|
// print a error message in the console
|
|
SINT8 nametonum(const char *name);
|
|
|
|
extern char motd[254], server_context[8];
|
|
extern UINT8 playernode[MAXPLAYERS];
|
|
/* consoleplayer of this player (splitscreen) */
|
|
extern UINT8 playerconsole[MAXPLAYERS];
|
|
|
|
INT32 D_NumPlayers(void);
|
|
INT32 D_NumPlayersInRace(void);
|
|
boolean D_IsPlayerHumanAndGaming(INT32 player_number);
|
|
|
|
void D_ResetTiccmds(void);
|
|
void D_ResetTiccmdAngle(UINT8 ss, angle_t angle);
|
|
ticcmd_t *D_LocalTiccmd(UINT8 ss);
|
|
|
|
tic_t GetLag(INT32 node);
|
|
UINT8 GetFreeXCmdSize(UINT8 playerid);
|
|
|
|
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
|
|
|
extern UINT8 hu_redownloadinggamestate;
|
|
|
|
extern UINT8 adminpassmd5[16];
|
|
extern boolean adminpasswordset;
|
|
|
|
extern boolean hu_stopped;
|
|
|
|
//
|
|
// SRB2Kart
|
|
//
|
|
|
|
void HandleSigfail(const char *string);
|
|
|
|
void DoSayPacket(SINT8 target, UINT8 flags, UINT8 source, char *message);
|
|
void DoSayPacketFromCommand(SINT8 target, size_t usedargs, UINT8 flags);
|
|
void DoVoicePacket(SINT8 target, UINT64 frame, const UINT8* opusdata, size_t len);
|
|
void SendServerNotice(SINT8 target, char *message);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#endif
|