29 #include "../../idlib/precompiled.h"
34 #include "../Session_local.h"
122 if ( lastPort >= NUM_SERVER_PORTS ) {
123 common->
Printf(
"Unable to open server network port.\n" );
216 for ( j = 0; j < 4; j++ ) {
219 if (
clients[i].channel.UnsentFragmentsLeft() ) {
249 bool addonReload =
false;
285 common->
Printf(
"net_serverReloadEngine enabled - doing a full reload\n" );
294 msg.
Init( msgBuf,
sizeof( msgBuf ) );
614 int i, previousIndex, currentIndex;
711 memset( &badAddress, 0,
sizeof( badAddress ) );
770 msg.
Init( msgBuf,
sizeof( msgBuf ) );
801 if ( !
clients[ clientNum ].channel.SendReliableMessage( msg ) ) {
813 int i, zombieTimeout, clientTimeout;
853 msg.
Init( msgBuf,
sizeof( msgBuf ) );
879 msg.
Init( msgBuf,
sizeof( msgBuf ) );
895 bool gameModifiedInfo;
899 gameModifiedInfo =
true;
901 gameModifiedInfo =
false;
911 msg.
Init( msgBuf,
sizeof( msgBuf ) );
914 if ( gameModifiedInfo || sendToAll ) {
920 #if ID_CLIENTINFO_TAGS
926 if ( gameModifiedInfo || sendToAll ) {
953 common->
Warning(
"idAsyncServer::UpdateUI: no info from game\n" );
973 msg.
Init( msgBuf,
sizeof( msgBuf ) );
978 #if ID_CLIENTINFO_TAGS
980 common->
DPrintf(
"user info %d to client %d: NULL base\n", userInfoNum, clientNum );
998 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1024 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1040 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1070 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1104 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1136 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1171 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1192 if ( !( clientInPVS[i >> 3] & ( 1 << ( i & 7 ) ) ) ) {
1202 for ( j = 0; j < numUsercmds; j++ ) {
1225 int i,
id, acknowledgeSequence, clientGameInitId, clientGameFrame, numUsercmds,
index;
1234 acknowledgeSequence = msg.
ReadLong();
1240 common->
Printf(
"ignore unreliable msg from client %d, gameInitId == ID_MAP_LOAD\n", clientNum );
1261 common->
Printf(
"ignore unreliable msg from client %d, wrong gameInit, old sequence\n", clientNum );
1303 common->
Printf(
"received empty message for client %d\n", clientNum );
1318 for ( last =
NULL, i = clientGameFrame - numUsercmds + 1; i <= clientGameFrame; i++ ) {
1335 common->
Printf(
"received user command for client %d, gameInitId = %d, gameFrame, %d gameTime %d\n", clientNum, clientGameInitId, client.
gameFrame, client.
gameTime );
1340 common->
Printf(
"unknown unreliable message %d from client %d\n",
id, clientNum );
1358 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1404 idStr replyPrintMsg;
1413 msg.
ReadString( client_guid,
sizeof( client_guid ) );
1417 common->
DPrintf(
"auth: invalid reply msg %d\n", replyMsg );
1449 if ( i >= MAX_CHALLENGES ) {
1468 msg = replyPrintMsg.
c_str();
1485 int i, clientId, oldest, oldestTime;
1492 oldestTime = 0x7fffffff;
1505 if ( i >= MAX_CHALLENGES ) {
1523 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1563 int serverChecksums[ MAX_PURE_PAKS ];
1564 int gamePakChecksum;
1568 if ( !serverChecksums[ 0 ] ) {
1570 common->
Warning(
"pure server has no pak files referenced" );
1576 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1581 while ( serverChecksums[ i ] ) {
1582 outMsg.
WriteLong( serverChecksums[ i++ ] );
1601 int serverChecksums[ MAX_PURE_PAKS ];
1603 int gamePakChecksum;
1606 if ( !serverChecksums[ 0 ] ) {
1608 common->
Warning(
"pure server has no pak files referenced" );
1612 common->
DPrintf(
"client %d: sending pure pak list (reliable channel) @ gameInitId %d\n", clientNum,
gameInitId );
1614 msg.
Init( msgBuf,
sizeof( msgBuf ) );
1620 while ( serverChecksums[ i ] ) {
1621 msg.
WriteLong( serverChecksums[ i++ ] );
1656 if ( challenge ==
challenges[i].challenge ) {
1661 if ( i == MAX_CHALLENGES ) {
1674 int clientNum, protocol, clientDataChecksum, challenge, clientId, ping, clientRate;
1679 int i, ichallenge, islot,
OS, numClients;
1691 clientDataChecksum = msg.
ReadLong();
1709 switch (
challenges[ ichallenge ].authState ) {
1722 const char *msg, *l_msg;
1737 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1751 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1778 msg.
ReadString( password,
sizeof( password ) );
1785 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1815 for ( islot = 0; islot < 3; islot++ ) {
1825 }
else if ( islot == 1 ) {
1833 }
else if ( islot == 2 ) {
1841 if ( clientNum < MAX_ASYNC_CLIENTS ) {
1845 strncpy(
clients[ clientNum ].guid, guid, 12 );
1852 if ( clientNum >= MAX_ASYNC_CLIENTS ) {
1860 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1871 InitClient( clientNum, clientId, clientRate );
1886 int i, numChecksums;
1887 int checksums[ MAX_PURE_PAKS ];
1888 int gamePakChecksum;
1889 int serverChecksums[ MAX_PURE_PAKS ];
1890 int serverGamePakChecksum;
1896 checksums[ numChecksums++ ] =
i;
1898 if ( numChecksums >= MAX_PURE_PAKS ) {
1899 common->
Warning(
"MAX_PURE_PAKS ( %d ) exceeded in idAsyncServer::ProcessPureMessage\n", MAX_PURE_PAKS );
1900 sprintf( reply,
"#str_07144" );
1910 assert( serverChecksums[ 0 ] );
1913 if ( serverGamePakChecksum != gamePakChecksum ) {
1915 sprintf( reply,
"#str_07145" );
1918 for ( i = 0; serverChecksums[
i ] != 0; i++ ) {
1919 if ( checksums[ i ] != serverChecksums[ i ] ) {
1921 sprintf( reply,
"pak missing ( 0x%x )\n", serverChecksums[ i ] );
1925 if ( checksums[ i ] != 0 ) {
1927 sprintf( reply,
"extra pak file referenced ( 0x%x )\n", checksums[ i ] );
1939 int iclient, challenge, clientId;
1972 int clientGameInitId;
1976 common->
DPrintf(
"client %d: ignoring reliable pure from an old gameInit (%d)\n", clientNum, clientGameInitId );
1982 common->
DPrintf(
"client %d: got reliable pure while != SCS_PUREWAIT, sending a reload\n", clientNum );
1983 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
1995 common->
DPrintf(
"client %d: passed pure checks (reliable channel)\n", clientNum );
2075 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2109 common->
Printf(
"server '%s' IP = %s\nprotocol %d.%d OS mask 0x%x\n",
2121 common->
Printf(
"client %2d: %s, ping = %d, rate = %d\n", i,
2173 if (
idStr::Icmp(
string,
"downloadRequest" ) == 0 ) {
2184 common->
Printf(
"auth message from master. net_LANServer is enabled, ignored.\n" );
2199 int i,
id, sequence;
2250 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2268 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2299 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2304 if ( i == clientNum ) {
2321 common->
Printf(
"LocalClientSendReliableMessage: no local client\n" );
2343 msg.
Init( msgBuf,
sizeof( msgBuf ) );
2379 int outgoingRate, incomingRate;
2380 float outgoingCompression, incomingCompression;
2403 msg.
Init( msgBuf,
sizeof( msgBuf ) );
2414 }
while( newPacket );
2518 common->
Printf(
"delay = %d msec, total outgoing rate = %d KB/s, total incoming rate = %d KB/s\n",
GetDelay(),
2528 if ( outgoingRate != -1 && incomingRate != -1 ) {
2529 common->
Printf(
"client %d: out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)\n",
2530 i, outgoingRate, outgoingCompression, incomingRate, incomingCompression );
2560 if (
clients[i].channel.UnsentFragmentsLeft() ) {
2578 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2594 common->
Printf(
"net_LANServer is enabled. Not sending heartbeats\n" );
2612 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2629 msg.
Init( msgBuf,
sizeof( msgBuf ) );
2675 int challenge, clientId, iclient, numPaks,
i;
2678 int dlSize[ MAX_PURE_PAKS ];
2706 common->
Warning(
"client requested unknown game pak 0x%x", dlGamePak );
2714 pakNames.
Append( pakbuf );
2719 while ( dlPakChecksum ) {
2722 common->
Warning(
"client requested an unknown pak 0x%x", dlPakChecksum );
2726 pakNames.
Append( pakbuf );
2731 for ( i = 0; i < pakNames.
Num(); i++ ) {
2735 paklist += pakNames[
i ].c_str();
2739 common->
DPrintf(
"got download request for %d paks - %s\n", numPaks - voidSlots, paklist.
c_str() );
2741 outMsg.
Init( msgBuf,
sizeof( msgBuf ) );
2756 next = strchr( token,
';' );
2763 type = atoi( token );
2765 common->
DPrintf(
"download request: redirect to URL %s\n", token );
2774 next = token =
NULL;
2779 next = strchr( token,
';' );
2786 int totalDlSize = 0;
2787 int numActualPaks = 0;
2794 for ( i = 0; i < pakURLs.
Num(); i++ ) {
2796 if ( !dlSize[ i ] || !pakURLs[ i ].Length() ) {
2801 totalDlSize += dlSize[
i ];
2817 if ( i == pakURLs.
Num() ) {
2821 common->
DPrintf(
"download request: download %d paks, %d bytes\n", numActualPaks, totalDlSize );
const int PING_RESEND_TIME
virtual void GetBestGameType(const char *map, const char *gametype, char buf[MAX_STRING_CHARS])=0
virtual const idDict * SetUserInfo(int clientNum, const idDict &userInfo, bool isClient, bool canModify)=0
const int MAX_ASYNC_CLIENTS
int GetIncomingRate(void) const
static int snPrintf(char *dest, int size, const char *fmt,...) id_attribute((format(printf
int SendMessage(idPort &port, const int time, const idBitMsg &msg)
int GetInt(const char *key, const char *defaultString="0") const
idStr & SetFileExtension(const char *extension)
virtual void ServerClientDisconnect(int clientNum)=0
virtual void ServerWriteInitialReliableMessages(int clientNum)=0
assert(prefInfo.fullscreenBtn)
static idCVar serverSnapshotDelay
int Cmp(const char *text) const
idCVarSystem * cvarSystem
static idCVar serverReloadEngine
void ProcessPureMessage(const netadr_t from, const idBitMsg &msg)
static idCVar serverMaxUsercmdRelay
bool Process(const netadr_t from, int time, idBitMsg &msg, int &sequence)
int GetNumIdleClients(void) const
virtual void virtual void virtual const idLangDict * GetLanguageDict(void)=0
bool IsActive(void) const
#define CONNECTIONLESS_MESSAGE_ID_MASK
virtual bool UpdateGamePakChecksums(void)=0
serverClientState_t clientState
netadr_t GetBoundAdr(void) const
ID_INLINE T Max(T x, T y)
void ExecuteMapChange(void)
bool Sys_IsLANAddress(const netadr_t adr)
const int ASYNC_PROTOCOL_VERSION
int acknowledgeSnapshotSequence
virtual const char * MessageBox(msgBoxType_t type, const char *message, const char *title=NULL, bool wait=false, const char *fire_yes=NULL, const char *fire_no=NULL, bool network=false)=0
void SetMaxOutgoingRate(int rate)
virtual void ServerClientBegin(int clientNum)=0
virtual void ClearPureChecksums(void)=0
#define ASYNC_PROTOCOL_MAJOR
bool VerifyChecksumMessage(int clientNum, const netadr_t *from, const idBitMsg &msg, idStr &reply, int OS)
idCVar com_showAsyncStats("com_showAsyncStats","0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT,"show async network stats")
int GetOutgoingRate(void) const
bool Sys_CompareNetAdrBase(const netadr_t a, const netadr_t b)
virtual int GetCVarInteger(const char *name) const =0
void SendApplySnapshotToClient(int clientNum, int sequence)
void SendReliableGameMessageExcluding(int clientNum, const idBitMsg &msg)
int GetRemaingData(void) const
int Sys_Milliseconds(void)
idFileSystem * fileSystem
void ProcessReliableClientMessages(int clientNum)
virtual allowReply_t ServerAllowClient(int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS])=0
virtual findFile_t FindFile(const char *path, bool scheduleAddons=false)=0
virtual void SetServerInfo(const idDict &serverInfo)=0
usercmd_t userCmds[MAX_USERCMD_BACKUP][MAX_ASYNC_CLIENTS]
bool IsClientInGame(int clientNum) const
void Init(const netadr_t adr, const int id)
GLenum GLsizei const GLvoid * string
virtual int ValidateDownloadPakForChecksum(int checksum, char path[MAX_STRING_CHARS], bool isGamePak)=0
void SendUserInfoBroadcast(int userInfoNum, const idDict &info, bool sendToAll=false)
virtual void SetCVarString(const char *name, const char *value, int flags=0)=0
void PacifierUpdate(void)
GLuint GLuint GLsizei GLenum type
void SendNextFragment(idPort &port, const int time)
int ReadString(char *buffer, int bufferSize) const
int GetNumClients(void) const
void Sys_Sleep(const int time)
void WriteString(const char *s, int maxLength=-1, bool make7Bit=true)
void Set(const char *key, const char *value)
bool serverReloadingEngine
static int ClampInt(int min, int max, int value)
bool ConnectionlessMessage(const netadr_t from, const idBitMsg &msg)
virtual int GetOSMask(void)=0
int ValidateChallenge(const netadr_t from, int challenge, int clientId)
static idCVar serverClientTimeout
netadr_t GetRemoteAddress(void) const
int Icmp(const char *text) const
int UpdateTime(int clamp)
void Init(byte *data, int length)
void CheckClientTimeouts(void)
int GetClientTimeSinceLastInput(int clientNum) const
bool ProcessMessage(const netadr_t from, idBitMsg &msg)
void WriteData(const void *data, int length)
int GetRemainingSpace(void) const
bool GetPacket(netadr_t &from, void *data, int &size, int maxSize)
const int MAX_MASTER_SERVERS
void ProcessReliablePure(int clientNum, const idBitMsg &msg)
static idCVar serverZombieTimeout
virtual void ServerClientConnect(int clientNum, const char *guid)=0
virtual void UpdatePureServerChecksums(void)=0
netadr_t GetAdr(void) const
virtual int GetChecksum(void) const =0
virtual void BufferCommandText(cmdExecution_t exec, const char *text)=0
serverClient_t clients[MAX_ASYNC_CLIENTS]
void WriteNetadr(const netadr_t adr)
float GetClientOutgoingCompression(int clientNum) const
bool ReadDeltaDict(idDict &dict, const idDict *base) const
virtual const idDict * GetUserInfo(int clientNum)=0
void SendPacket(const netadr_t to, const void *data, int size)
void SendSyncedCvarsBroadcast(const idDict &cvars)
const int AUTHORIZE_TIMEOUT
const int NOINPUT_IDLE_TIME
void ProcessConnectMessage(const netadr_t from, const idBitMsg &msg)
const int GAME_INIT_ID_MAP_LOAD
const char * GetString(const char *key, const char *defaultString="") const
const int ASYNC_PROTOCOL_MINOR
static idAsyncServer server
static void WriteUserCmdDelta(idBitMsg &msg, const usercmd_t &cmd, const usercmd_t *base)
virtual void SetLocalClient(int clientNum)=0
bool GetReliableMessage(idBitMsg &msg)
virtual void virtual void virtual void DWarning(const char *fmt,...) id_attribute((format(printf
const int MAX_USERCMD_RELAY
bool GetBool(const char *key, const char *defaultString="0") const
virtual const char * GetCVarString(const char *name) const =0
void BeginReading(void) const
void SendSyncedCvarsToClient(int clientNum, const idDict &cvars)
void LocalClientInput(void)
void SetInteger(const int value)
int GetInteger(void) const
void PrintOOB(const netadr_t to, int opcode, const char *string)
void ProcessGetInfoMessage(const netadr_t from, const idBitMsg &msg)
const char * authReplyMsg[]
void ClearReliableMessages(void)
void ProcessUnreliableClientMessage(int clientNum, const idBitMsg &msg)
bool ReadyToSend(const int time) const
void SendUserInfoToClient(int clientNum, int userInfoNum, const idDict &info)
bool SendPingToClient(int clientNum)
challenge_t challenges[MAX_CHALLENGES]
const char * GetString(const char *str) const
idDict userInfo[MAX_ASYNC_CLIENTS]
virtual gameReturn_t RunFrame(const usercmd_t *clientCmds)=0
void SendPrintBroadcast(const char *string)
bool InitForPort(int portNumber)
void BeginLocalClient(void)
static idCVar serverDedicated
void GetAsyncStatsAvgMsg(idStr &msg)
void ReadNetadr(netadr_t *adr) const
idUsercmdGen * usercmdGen
bool SendPureServerMessage(const netadr_t to, int OS)
int GetClientPrediction(int clientNum) const
void PrintLocalServerInfo(void)
static idCVar allowCheats
bool SendReliablePureToClient(int clientNum)
int GetClientIncomingRate(int clientNum) const
virtual void Printf(const char *fmt,...) id_attribute((format(printf
static idCVar serverRemoteConsolePassword
static netadr_t GetMasterAddress(void)
void ExecuteMapChange(bool noFadeWipe=false)
const char * Sys_NetAdrToString(const netadr_t a)
void SendEnterGameToClient(int clientNum)
static const int stats_numsamples
idDeclManager * declManager
void ProcessDownloadRequestMessage(const netadr_t from, const idBitMsg &msg)
mapSpawnData_t mapSpawnData
virtual void ThrottleUserInfo(void)=0
virtual bool RunningD3XP(void)=0
void LocalClientSendReliableMessage(const idBitMsg &msg)
virtual void GetPureServerChecksums(int checksums[MAX_PURE_PAKS], int OS, int *gamePakChecksum)=0
const int EMPTY_RESEND_TIME
void SendReliableMessage(int clientNum, const idBitMsg &msg)
static bool UsercmdInputChanged(const usercmd_t &previousUserCmd, const usercmd_t ¤tUserCmd)
virtual int GetModifiedFlags(void) const =0
float GetIncomingCompression(void) const
int Append(const type &obj)
LPCSTR GetString(LPCSTR psPrompt)
int GetClientOutgoingRate(int clientNum) const
static void ExecuteSessionCommand(const char *sessCmd)
void InitClient(int clientNum, int clientId, int clientRate)
int numDuplicatedUsercmds
void SendReliableGameMessage(int clientNum, const idBitMsg &msg)
bool UnsentFragmentsLeft(void) const
void DropClient(int clientNum, const char *reason)
void ProcessChallengeMessage(const netadr_t from, const idBitMsg &msg)
static signed char ClampChar(int i)
#define CONNECTIONLESS_MESSAGE_ID
void UpdateUI(int clientNum)
bool WriteDeltaDict(const idDict &dict, const idDict *base)
int GetIncomingRate(void) const
int GetClientTimeSinceLastPacket(int clientNum) const
virtual void ResetFlaggedVariables(int flags)=0
float GetIncomingPacketLoss(void) const
void ProcessRemoteConsoleMessage(const netadr_t from, const idBitMsg &msg)
void RConRedirect(const char *string)
static bool DuplicateUsercmd(const usercmd_t &previousUserCmd, usercmd_t ¤tUserCmd, int frame, int time)
void ProcessAuthMessage(const idBitMsg &msg)
virtual void ServerWriteSnapshot(int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients)=0
float GetClientIncomingCompression(int clientNum) const
float GetClientIncomingPacketLoss(int clientNum) const
virtual void BeginRedirect(char *buffer, int buffersize, void(*flush)(const char *))=0
authReplyMsg_t authReplyMsg
const char * c_str(void) const
bool SendSnapshotToClient(int clientNum)
int stats_outrate[stats_numsamples]
static idCVar serverMaxClientRate
void SendPrintToClient(int clientNum, const char *string)
void UpdateAsyncStatsAvg(void)
bool SendEmptyToClient(int clientNum, bool force=false)
void SetBool(const bool value)
char sessionCommand[MAX_STRING_CHARS]
void MasterHeartbeat(bool force=false)
virtual void EndRedirect(void)=0
virtual const idDict * MoveCVarsToDict(int flags) const =0
bool GetPacketBlocking(netadr_t &from, void *data, int &size, int maxSize, int timeout)
void RemoteConsoleOutput(const char *string)
int GetMaxOutgoingRate(void)
const int MAX_USERCMD_BACKUP
char * va(const char *fmt,...)
void ClearClient(int clientNum)
virtual void ServerProcessReliableMessage(int clientNum, const idBitMsg &msg)=0
void WriteBits(int value, int numBits)
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
void InitLocalClient(int clientNum)
static void ReadUserCmdDelta(const idBitMsg &msg, usercmd_t &cmd, const usercmd_t *base)
idCVar password("password","", CVAR_GAME|CVAR_NOCHEAT,"client password used when connecting")
void SendGameInitToClient(int clientNum)
virtual bool DownloadRequest(const char *IP, const char *guid, const char *paks, char urls[MAX_STRING_CHARS])=0
const int MIN_RECONNECT_TIME
virtual usercmd_t GetDirectUsercmd(void)=0
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
ID_INLINE T Min(T x, T y)
virtual bool ServerApplySnapshot(int clientNum, int sequence)=0
int sprintf(idStr &string, const char *fmt,...)
virtual void ClearModifiedFlags(int flags)=0
float GetOutgoingCompression(void) const
const char * authReplyStr[]
int GetClientPing(int clientNum) const
void ProcessConnectionLessMessages(void)
virtual void SetCVarsFromDict(const idDict &dict)=0
int ReadShort(void) const
static signed short ClampShort(int i)
void DuplicateUsercmds(int frame, int time)
int GetOutgoingRate(void) const