AsyncServer.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. 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.
  17. 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.
  18. ===========================================================================
  19. */
  20. #ifndef __ASYNCSERVER_H__
  21. #define __ASYNCSERVER_H__
  22. /*
  23. ===============================================================================
  24. Network Server for asynchronous networking.
  25. ===============================================================================
  26. */
  27. // MAX_CHALLENGES is made large to prevent a denial of service attack that could cycle
  28. // all of them out before legitimate users connected
  29. const int MAX_CHALLENGES = 1024;
  30. // if we don't hear from authorize server, assume it is down
  31. const int AUTHORIZE_TIMEOUT = 5000;
  32. // states for the server's authorization process
  33. typedef enum {
  34. CDK_WAIT = 0, // we are waiting for a confirm/deny from auth
  35. // this is subject to timeout if we don't hear from auth
  36. // or a permanent wait if auth said so
  37. CDK_OK,
  38. CDK_ONLYLAN,
  39. CDK_PUREWAIT,
  40. CDK_PUREOK,
  41. CDK_MAXSTATES
  42. } authState_t;
  43. // states from the auth server, while the client is in CDK_WAIT
  44. typedef enum {
  45. AUTH_NONE = 0, // no reply yet
  46. AUTH_OK, // this client is good
  47. AUTH_WAIT, // wait - keep sending me srvAuth though
  48. AUTH_DENY, // denied - don't send me anything about this client anymore
  49. AUTH_MAXSTATES
  50. } authReply_t;
  51. // message from auth to be forwarded back to the client
  52. // some are locally hardcoded to save space, auth has the possibility to send a custom reply
  53. typedef enum {
  54. AUTH_REPLY_WAITING = 0, // waiting on an initial reply from auth
  55. AUTH_REPLY_UNKNOWN, // client unknown to auth
  56. AUTH_REPLY_DENIED, // access denied
  57. AUTH_REPLY_PRINT, // custom message
  58. AUTH_REPLY_SRVWAIT, // auth server replied and tells us he's working on it
  59. AUTH_REPLY_MAXSTATES
  60. } authReplyMsg_t;
  61. typedef struct challenge_s {
  62. netadr_t address; // client address
  63. int clientId; // client identification
  64. int challenge; // challenge code
  65. int time; // time the challenge was created
  66. int pingTime; // time the challenge response was sent to client
  67. bool connected; // true if the client is connected
  68. authState_t authState; // local state regarding the client
  69. authReply_t authReply; // cd key check replies
  70. authReplyMsg_t authReplyMsg; // default auth messages
  71. idStr authReplyPrint; // custom msg
  72. char guid[12]; // guid
  73. int OS;
  74. } challenge_t;
  75. typedef enum {
  76. SCS_FREE, // can be reused for a new connection
  77. SCS_ZOMBIE, // client has been disconnected, but don't reuse connection for a couple seconds
  78. SCS_PUREWAIT, // client needs to update it's pure checksums before we can go further
  79. SCS_CONNECTED, // client is connected
  80. SCS_INGAME // client is in the game
  81. } serverClientState_t;
  82. typedef struct serverClient_s {
  83. int OS;
  84. int clientId;
  85. serverClientState_t clientState;
  86. int clientPrediction;
  87. int clientAheadTime;
  88. int clientRate;
  89. int clientPing;
  90. int gameInitSequence;
  91. int gameFrame;
  92. int gameTime;
  93. idMsgChannel channel;
  94. int lastConnectTime;
  95. int lastEmptyTime;
  96. int lastPingTime;
  97. int lastSnapshotTime;
  98. int lastPacketTime;
  99. int lastInputTime;
  100. int snapshotSequence;
  101. int acknowledgeSnapshotSequence;
  102. int numDuplicatedUsercmds;
  103. char guid[12]; // Even Balance - M. Quinn
  104. } serverClient_t;
  105. class idAsyncServer {
  106. public:
  107. idAsyncServer();
  108. bool InitPort( void );
  109. void ClosePort( void );
  110. void Spawn( void );
  111. void Kill( void );
  112. void ExecuteMapChange( void );
  113. int GetPort( void ) const;
  114. netadr_t GetBoundAdr( void ) const;
  115. bool IsActive( void ) const { return active; }
  116. int GetDelay( void ) const { return gameTimeResidual; }
  117. int GetOutgoingRate( void ) const;
  118. int GetIncomingRate( void ) const;
  119. bool IsClientInGame( int clientNum ) const;
  120. int GetClientPing( int clientNum ) const;
  121. int GetClientPrediction( int clientNum ) const;
  122. int GetClientTimeSinceLastPacket( int clientNum ) const;
  123. int GetClientTimeSinceLastInput( int clientNum ) const;
  124. int GetClientOutgoingRate( int clientNum ) const;
  125. int GetClientIncomingRate( int clientNum ) const;
  126. float GetClientOutgoingCompression( int clientNum ) const;
  127. float GetClientIncomingCompression( int clientNum ) const;
  128. float GetClientIncomingPacketLoss( int clientNum ) const;
  129. int GetNumClients( void ) const;
  130. int GetNumIdleClients( void ) const;
  131. int GetLocalClientNum( void ) const { return localClientNum; }
  132. void RunFrame( void );
  133. void ProcessConnectionLessMessages( void );
  134. void RemoteConsoleOutput( const char *string );
  135. void SendReliableGameMessage( int clientNum, const idBitMsg &msg );
  136. void SendReliableGameMessageExcluding( int clientNum, const idBitMsg &msg );
  137. void LocalClientSendReliableMessage( const idBitMsg &msg );
  138. void MasterHeartbeat( bool force = false );
  139. void DropClient( int clientNum, const char *reason );
  140. void PacifierUpdate( void );
  141. void UpdateUI( int clientNum );
  142. void UpdateAsyncStatsAvg( void );
  143. void GetAsyncStatsAvgMsg( idStr &msg );
  144. void PrintLocalServerInfo( void );
  145. private:
  146. bool active; // true if server is active
  147. int realTime; // absolute time
  148. int serverTime; // local server time
  149. idPort serverPort; // UDP port
  150. int serverId; // server identification
  151. int serverDataChecksum; // checksum of the data used by the server
  152. int localClientNum; // local client on listen server
  153. challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
  154. serverClient_t clients[MAX_ASYNC_CLIENTS]; // clients
  155. usercmd_t userCmds[MAX_USERCMD_BACKUP][MAX_ASYNC_CLIENTS];
  156. int gameInitId; // game initialization identification
  157. int gameFrame; // local game frame
  158. int gameTime; // local game time
  159. int gameTimeResidual; // left over time from previous frame
  160. netadr_t rconAddress;
  161. int nextHeartbeatTime;
  162. int nextAsyncStatsTime;
  163. bool serverReloadingEngine; // flip-flop to not loop over when net_serverReloadEngine is on
  164. bool noRconOutput; // for default rcon response when command is silent
  165. int lastAuthTime; // global for auth server timeout
  166. // track the max outgoing rate over the last few secs to watch for spikes
  167. // dependent on net_serverSnapshotDelay. 50ms, for a 3 seconds backlog -> 60 samples
  168. static const int stats_numsamples = 60;
  169. int stats_outrate[ stats_numsamples ];
  170. int stats_current;
  171. int stats_average_sum;
  172. int stats_max;
  173. int stats_max_index;
  174. void PrintOOB( const netadr_t to, int opcode, const char *string );
  175. void DuplicateUsercmds( int frame, int time );
  176. void ClearClient( int clientNum );
  177. void InitClient( int clientNum, int clientId, int clientRate );
  178. void InitLocalClient( int clientNum );
  179. void BeginLocalClient( void );
  180. void LocalClientInput( void );
  181. void CheckClientTimeouts( void );
  182. void SendPrintBroadcast( const char *string );
  183. void SendPrintToClient( int clientNum, const char *string );
  184. void SendUserInfoBroadcast( int userInfoNum, const idDict &info, bool sendToAll = false );
  185. void SendUserInfoToClient( int clientNum, int userInfoNum, const idDict &info );
  186. void SendSyncedCvarsBroadcast( const idDict &cvars );
  187. void SendSyncedCvarsToClient( int clientNum, const idDict &cvars );
  188. void SendApplySnapshotToClient( int clientNum, int sequence );
  189. bool SendEmptyToClient( int clientNum, bool force = false );
  190. bool SendPingToClient( int clientNum );
  191. void SendGameInitToClient( int clientNum );
  192. bool SendSnapshotToClient( int clientNum );
  193. void ProcessUnreliableClientMessage( int clientNum, const idBitMsg &msg );
  194. void ProcessReliableClientMessages( int clientNum );
  195. void ProcessChallengeMessage( const netadr_t from, const idBitMsg &msg );
  196. void ProcessConnectMessage( const netadr_t from, const idBitMsg &msg );
  197. void ProcessRemoteConsoleMessage( const netadr_t from, const idBitMsg &msg );
  198. void ProcessGetInfoMessage( const netadr_t from, const idBitMsg &msg );
  199. bool ConnectionlessMessage( const netadr_t from, const idBitMsg &msg );
  200. bool ProcessMessage( const netadr_t from, idBitMsg &msg );
  201. void ProcessAuthMessage( const idBitMsg &msg );
  202. bool SendPureServerMessage( const netadr_t to, int OS ); // returns false if no pure paks on the list
  203. void ProcessPureMessage( const netadr_t from, const idBitMsg &msg );
  204. int ValidateChallenge( const netadr_t from, int challenge, int clientId ); // returns -1 if validate failed
  205. bool SendReliablePureToClient( int clientNum );
  206. void ProcessReliablePure( int clientNum, const idBitMsg &msg );
  207. 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
  208. void SendReliableMessage( int clientNum, const idBitMsg &msg ); // checks for overflow and disconnects the faulty client
  209. int UpdateTime( int clamp );
  210. void SendEnterGameToClient( int clientNum );
  211. void ProcessDownloadRequestMessage( const netadr_t from, const idBitMsg &msg );
  212. };
  213. #endif /* !__ASYNCSERVER_H__ */