123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- /*
- ===========================================================================
- 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__
- /*
- ===============================================================================
- 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__ */
|