mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-11-27 14:42:23 +00:00
736ec20d4d
Don't include the lazy precompiled.h everywhere, only what's required for the compilation unit. platform.h needs to be included instead to provide all essential defines and types. All includes use the relative path to the neo or the game specific root. Move all idlib related includes from idlib/Lib.h to precompiled.h. precompiled.h still exists for the MFC stuff in tools/. Add some missing header guards.
261 lines
10 KiB
C++
261 lines
10 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifndef __ASYNCSERVER_H__
|
|
#define __ASYNCSERVER_H__
|
|
|
|
#include "framework/UsercmdGen.h"
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
Network Server for asynchronous networking.
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
// MAX_CHALLENGES is made large to prevent a denial of service attack that could cycle
|
|
// all of them out before legitimate users connected
|
|
const int MAX_CHALLENGES = 1024;
|
|
|
|
// if we don't hear from authorize server, assume it is down
|
|
const int AUTHORIZE_TIMEOUT = 5000;
|
|
|
|
// states for the server's authorization process
|
|
typedef enum {
|
|
CDK_WAIT = 0, // we are waiting for a confirm/deny from auth
|
|
// this is subject to timeout if we don't hear from auth
|
|
// or a permanent wait if auth said so
|
|
CDK_OK,
|
|
CDK_ONLYLAN,
|
|
CDK_PUREWAIT,
|
|
CDK_PUREOK,
|
|
CDK_MAXSTATES
|
|
} authState_t;
|
|
|
|
// states from the auth server, while the client is in CDK_WAIT
|
|
typedef enum {
|
|
AUTH_NONE = 0, // no reply yet
|
|
AUTH_OK, // this client is good
|
|
AUTH_WAIT, // wait - keep sending me srvAuth though
|
|
AUTH_DENY, // denied - don't send me anything about this client anymore
|
|
AUTH_MAXSTATES
|
|
} authReply_t;
|
|
|
|
// message from auth to be forwarded back to the client
|
|
// some are locally hardcoded to save space, auth has the possibility to send a custom reply
|
|
typedef enum {
|
|
AUTH_REPLY_WAITING = 0, // waiting on an initial reply from auth
|
|
AUTH_REPLY_UNKNOWN, // client unknown to auth
|
|
AUTH_REPLY_DENIED, // access denied
|
|
AUTH_REPLY_PRINT, // custom message
|
|
AUTH_REPLY_SRVWAIT, // auth server replied and tells us he's working on it
|
|
AUTH_REPLY_MAXSTATES
|
|
} authReplyMsg_t;
|
|
|
|
typedef struct challenge_s {
|
|
netadr_t address; // client address
|
|
int clientId; // client identification
|
|
int challenge; // challenge code
|
|
int time; // time the challenge was created
|
|
int pingTime; // time the challenge response was sent to client
|
|
bool connected; // true if the client is connected
|
|
authState_t authState; // local state regarding the client
|
|
authReply_t authReply; // cd key check replies
|
|
authReplyMsg_t authReplyMsg; // default auth messages
|
|
idStr authReplyPrint; // custom msg
|
|
char guid[12]; // guid
|
|
int OS;
|
|
} challenge_t;
|
|
|
|
typedef enum {
|
|
SCS_FREE, // can be reused for a new connection
|
|
SCS_ZOMBIE, // client has been disconnected, but don't reuse connection for a couple seconds
|
|
SCS_PUREWAIT, // client needs to update it's pure checksums before we can go further
|
|
SCS_CONNECTED, // client is connected
|
|
SCS_INGAME // client is in the game
|
|
} serverClientState_t;
|
|
|
|
typedef struct serverClient_s {
|
|
int OS;
|
|
int clientId;
|
|
serverClientState_t clientState;
|
|
int clientPrediction;
|
|
int clientAheadTime;
|
|
int clientRate;
|
|
int clientPing;
|
|
|
|
int gameInitSequence;
|
|
int gameFrame;
|
|
int gameTime;
|
|
|
|
idMsgChannel channel;
|
|
int lastConnectTime;
|
|
int lastEmptyTime;
|
|
int lastPingTime;
|
|
int lastSnapshotTime;
|
|
int lastPacketTime;
|
|
int lastInputTime;
|
|
int snapshotSequence;
|
|
int acknowledgeSnapshotSequence;
|
|
int numDuplicatedUsercmds;
|
|
|
|
char guid[12]; // Even Balance - M. Quinn
|
|
|
|
} serverClient_t;
|
|
|
|
|
|
class idAsyncServer {
|
|
public:
|
|
idAsyncServer();
|
|
|
|
bool InitPort( void );
|
|
void ClosePort( void );
|
|
void Spawn( void );
|
|
void Kill( void );
|
|
void ExecuteMapChange( void );
|
|
|
|
int GetPort( void ) const;
|
|
netadr_t GetBoundAdr( void ) const;
|
|
bool IsActive( void ) const { return active; }
|
|
int GetDelay( void ) const { return gameTimeResidual; }
|
|
int GetOutgoingRate( void ) const;
|
|
int GetIncomingRate( void ) const;
|
|
bool IsClientInGame( int clientNum ) const;
|
|
int GetClientPing( int clientNum ) const;
|
|
int GetClientPrediction( int clientNum ) const;
|
|
int GetClientTimeSinceLastPacket( int clientNum ) const;
|
|
int GetClientTimeSinceLastInput( int clientNum ) const;
|
|
int GetClientOutgoingRate( int clientNum ) const;
|
|
int GetClientIncomingRate( int clientNum ) const;
|
|
float GetClientOutgoingCompression( int clientNum ) const;
|
|
float GetClientIncomingCompression( int clientNum ) const;
|
|
float GetClientIncomingPacketLoss( int clientNum ) const;
|
|
int GetNumClients( void ) const;
|
|
int GetNumIdleClients( void ) const;
|
|
int GetLocalClientNum( void ) const { return localClientNum; }
|
|
|
|
void RunFrame( void );
|
|
void ProcessConnectionLessMessages( void );
|
|
void RemoteConsoleOutput( const char *string );
|
|
void SendReliableGameMessage( int clientNum, const idBitMsg &msg );
|
|
void SendReliableGameMessageExcluding( int clientNum, const idBitMsg &msg );
|
|
void LocalClientSendReliableMessage( const idBitMsg &msg );
|
|
|
|
void MasterHeartbeat( bool force = false );
|
|
void DropClient( int clientNum, const char *reason );
|
|
|
|
void PacifierUpdate( void );
|
|
|
|
void UpdateUI( int clientNum );
|
|
|
|
void UpdateAsyncStatsAvg( void );
|
|
void GetAsyncStatsAvgMsg( idStr &msg );
|
|
|
|
void PrintLocalServerInfo( void );
|
|
|
|
private:
|
|
bool active; // true if server is active
|
|
int realTime; // absolute time
|
|
|
|
int serverTime; // local server time
|
|
idPort serverPort; // UDP port
|
|
int serverId; // server identification
|
|
int serverDataChecksum; // checksum of the data used by the server
|
|
int localClientNum; // local client on listen server
|
|
|
|
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
|
|
serverClient_t clients[MAX_ASYNC_CLIENTS]; // clients
|
|
usercmd_t userCmds[MAX_USERCMD_BACKUP][MAX_ASYNC_CLIENTS];
|
|
|
|
int gameInitId; // game initialization identification
|
|
int gameFrame; // local game frame
|
|
int gameTime; // local game time
|
|
int gameTimeResidual; // left over time from previous frame
|
|
|
|
netadr_t rconAddress;
|
|
|
|
int nextHeartbeatTime;
|
|
int nextAsyncStatsTime;
|
|
|
|
bool serverReloadingEngine; // flip-flop to not loop over when net_serverReloadEngine is on
|
|
|
|
bool noRconOutput; // for default rcon response when command is silent
|
|
|
|
int lastAuthTime; // global for auth server timeout
|
|
|
|
// track the max outgoing rate over the last few secs to watch for spikes
|
|
// dependent on net_serverSnapshotDelay. 50ms, for a 3 seconds backlog -> 60 samples
|
|
static const int stats_numsamples = 60;
|
|
int stats_outrate[ stats_numsamples ];
|
|
int stats_current;
|
|
int stats_average_sum;
|
|
int stats_max;
|
|
int stats_max_index;
|
|
|
|
void PrintOOB( const netadr_t to, int opcode, const char *string );
|
|
void DuplicateUsercmds( int frame, int time );
|
|
void ClearClient( int clientNum );
|
|
void InitClient( int clientNum, int clientId, int clientRate );
|
|
void InitLocalClient( int clientNum );
|
|
void BeginLocalClient( void );
|
|
void LocalClientInput( void );
|
|
void CheckClientTimeouts( void );
|
|
void SendPrintBroadcast( const char *string );
|
|
void SendPrintToClient( int clientNum, const char *string );
|
|
void SendUserInfoBroadcast( int userInfoNum, const idDict &info, bool sendToAll = false );
|
|
void SendUserInfoToClient( int clientNum, int userInfoNum, const idDict &info );
|
|
void SendSyncedCvarsBroadcast( const idDict &cvars );
|
|
void SendSyncedCvarsToClient( int clientNum, const idDict &cvars );
|
|
void SendApplySnapshotToClient( int clientNum, int sequence );
|
|
bool SendEmptyToClient( int clientNum, bool force = false );
|
|
bool SendPingToClient( int clientNum );
|
|
void SendGameInitToClient( int clientNum );
|
|
bool SendSnapshotToClient( int clientNum );
|
|
void ProcessUnreliableClientMessage( int clientNum, const idBitMsg &msg );
|
|
void ProcessReliableClientMessages( int clientNum );
|
|
void ProcessChallengeMessage( const netadr_t from, const idBitMsg &msg );
|
|
void ProcessConnectMessage( const netadr_t from, const idBitMsg &msg );
|
|
void ProcessRemoteConsoleMessage( const netadr_t from, const idBitMsg &msg );
|
|
void ProcessGetInfoMessage( const netadr_t from, const idBitMsg &msg );
|
|
bool ConnectionlessMessage( const netadr_t from, const idBitMsg &msg );
|
|
bool ProcessMessage( const netadr_t from, idBitMsg &msg );
|
|
void ProcessAuthMessage( const idBitMsg &msg );
|
|
bool SendPureServerMessage( const netadr_t to, int OS ); // returns false if no pure paks on the list
|
|
void ProcessPureMessage( const netadr_t from, const idBitMsg &msg );
|
|
int ValidateChallenge( const netadr_t from, int challenge, int clientId ); // returns -1 if validate failed
|
|
bool SendReliablePureToClient( int clientNum );
|
|
void ProcessReliablePure( int clientNum, const idBitMsg &msg );
|
|
bool VerifyChecksumMessage( int clientNum, const netadr_t *from, const idBitMsg &msg, idStr &reply, int OS ); // if from is NULL, clientNum is used for error messages
|
|
void SendReliableMessage( int clientNum, const idBitMsg &msg ); // checks for overflow and disconnects the faulty client
|
|
int UpdateTime( int clamp );
|
|
void SendEnterGameToClient( int clientNum );
|
|
void ProcessDownloadRequestMessage( const netadr_t from, const idBitMsg &msg );
|
|
};
|
|
|
|
#endif /* !__ASYNCSERVER_H__ */
|