Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef BASECLIENT_H
  7. #define BASECLIENT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include <const.h>
  12. #include <checksum_crc.h>
  13. #include <iclient.h>
  14. #include <protocol.h>
  15. #include <iservernetworkable.h>
  16. #include <bspfile.h>
  17. #include <KeyValues.h>
  18. #include <bitvec.h>
  19. #include <igameevents.h>
  20. #include "smartptr.h"
  21. #include "userid.h"
  22. #include "tier1/bitbuf.h"
  23. #include "steam/steamclientpublic.h"
  24. // class CClientFrame;
  25. class CBaseServer;
  26. class CClientFrame;
  27. struct player_info_s;
  28. class CFrameSnapshot;
  29. class CEventInfo;
  30. struct Spike_t
  31. {
  32. public:
  33. Spike_t() :
  34. m_nBits( 0 )
  35. {
  36. m_szDesc[ 0 ] = 0;
  37. }
  38. char m_szDesc[ 64 ];
  39. int m_nBits;
  40. };
  41. class CNetworkStatTrace
  42. {
  43. public:
  44. CNetworkStatTrace() :
  45. m_nMinWarningBytes( 0 ), m_nStartBit( 0 ), m_nCurBit( 0 ), m_StartSendTime(0.0)
  46. {
  47. }
  48. int m_nMinWarningBytes;
  49. int m_nStartBit;
  50. int m_nCurBit;
  51. CUtlVector< Spike_t > m_Records;
  52. double m_StartSendTime;
  53. };
  54. class CBaseClient : public IGameEventListener2, public IClient, public IClientMessageHandler
  55. {
  56. typedef struct CustomFile_s
  57. {
  58. CRC32_t crc; //file CRC
  59. unsigned int reqID; // download request ID
  60. } CustomFile_t;
  61. public:
  62. CBaseClient();
  63. virtual ~CBaseClient();
  64. public:
  65. int GetPlayerSlot() const { return m_nClientSlot; };
  66. int GetUserID() const { return m_UserID; };
  67. const USERID_t GetNetworkID() const;
  68. const char *GetClientName() const { return m_Name; };
  69. INetChannel *GetNetChannel() { return m_NetChannel; };
  70. IServer *GetServer() { return (IServer*)m_Server; };
  71. const char *GetUserSetting(const char *cvar) const;
  72. const char *GetNetworkIDString() const;
  73. uint GetFriendsID() const { return m_nFriendsID; }
  74. const char *GetFriendsName() const { return m_FriendsName; }
  75. void UpdateName( const char *pszDefault );
  76. int GetClientChallenge() const { return m_clientChallenge; }
  77. void SetReportThisFakeClient( bool bReport ) { m_bReportFakeClient = bReport; }
  78. bool ShouldReportThisFakeClient( void ) const { return m_bReportFakeClient; }
  79. virtual void Connect( const char * szName, int nUserID, INetChannel *pNetChannel, bool bFakePlayer, int clientChallenge );
  80. virtual void Inactivate( void );
  81. virtual void Reconnect( void );
  82. virtual void Disconnect( PRINTF_FORMAT_STRING const char *reason, ... );
  83. virtual void SetRate( int nRate, bool bForce );
  84. virtual int GetRate( void ) const;
  85. virtual void SetUpdateRate( int nUpdateRate, bool bForce );
  86. virtual int GetUpdateRate( void ) const;
  87. virtual void Clear( void );
  88. virtual void DemoRestart( void ); // called when client started demo recording
  89. virtual int GetMaxAckTickCount() const;
  90. virtual bool ExecuteStringCommand( const char *s );
  91. virtual bool SendNetMsg(INetMessage &msg, bool bForceReliable = false);
  92. virtual void ClientPrintf (PRINTF_FORMAT_STRING const char *fmt, ...);
  93. virtual bool IsConnected( void ) const { return m_nSignonState >= SIGNONSTATE_CONNECTED; };
  94. virtual bool IsSpawned( void ) const { return m_nSignonState >= SIGNONSTATE_NEW; };
  95. virtual bool IsActive( void ) const { return m_nSignonState == SIGNONSTATE_FULL; };
  96. virtual bool IsFakeClient( void ) const { return m_bFakePlayer; };
  97. virtual bool IsHLTV( void ) const { return m_bIsHLTV; }
  98. #if defined( REPLAY_ENABLED )
  99. virtual bool IsReplay() const { return m_bIsReplay; }
  100. #endif
  101. void OnSignonStateFull();
  102. // Is an actual human player or splitscreen player (not a bot and not a HLTV slot)
  103. virtual bool IsHearingClient( int index ) const { return false; };
  104. virtual bool IsProximityHearingClient( int index ) const { return false; };
  105. virtual void SetMaxRoutablePayloadSize( int nMaxRoutablePayloadSize );
  106. virtual bool IsSplitScreenUser( void ) const { return false; } // !KLUDGE! We don't have splitscreen support, but this makes merges easier
  107. public: // IClientMessageHandlers
  108. PROCESS_NET_MESSAGE( Tick );
  109. PROCESS_NET_MESSAGE( StringCmd );
  110. PROCESS_NET_MESSAGE( SetConVar );
  111. PROCESS_NET_MESSAGE( SignonState );
  112. PROCESS_CLC_MESSAGE( ClientInfo );
  113. PROCESS_CLC_MESSAGE( BaselineAck );
  114. PROCESS_CLC_MESSAGE( ListenEvents );
  115. PROCESS_CLC_MESSAGE( CmdKeyValues );
  116. virtual void ConnectionStart(INetChannel *chan);
  117. public: // IGameEventListener
  118. virtual void FireGameEvent( IGameEvent *event );
  119. public:
  120. virtual bool UpdateAcknowledgedFramecount(int tick);
  121. virtual bool ShouldSendMessages( void );
  122. virtual void UpdateSendState( void );
  123. void ForceFullUpdate( void ) { UpdateAcknowledgedFramecount(-1); }
  124. virtual bool FillUserInfo( player_info_s &userInfo );
  125. virtual void UpdateUserSettings();
  126. virtual bool SetSignonState(int state, int spawncount);
  127. virtual void WriteGameSounds(bf_write &buf);
  128. virtual CClientFrame *GetDeltaFrame( int nTick );
  129. virtual void SendSnapshot( CClientFrame *pFrame );
  130. virtual bool SendServerInfo( void );
  131. virtual bool SendSignonData( void );
  132. virtual void SpawnPlayer( void );
  133. virtual void ActivatePlayer( void );
  134. virtual void SetName( const char * playerName );
  135. virtual void SetUserCVar( const char *cvar, const char *value);
  136. virtual void FreeBaselines();
  137. virtual bool IgnoreTempEntity( CEventInfo *event );
  138. void SetSteamID( const CSteamID &steamID );
  139. void ClientRequestNameChange( const char *pszName );
  140. bool IsTracing() const { return m_iTracing > 0; }
  141. void TraceNetworkData( bf_write &msg, PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 3, 4 );
  142. void TraceNetworkMsg( int nBits, PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 3, 4 );
  143. bool IsFullyAuthenticated( void ) { return m_bFullyAuthenticated; }
  144. void SetFullyAuthenticated( void ) { m_bFullyAuthenticated = true; }
  145. void CheckFlushNameChange( bool bShowStatusMessage = false );
  146. bool IsNameChangeOnCooldown( bool bShowStatusMessage = false );
  147. void SetPlayerNameLocked( bool bValue ) { m_bPlayerNameLocked = bValue; }
  148. bool IsPlayerNameLocked( void ) { return m_bPlayerNameLocked; }
  149. private:
  150. void OnRequestFullUpdate();
  151. public:
  152. // Array index in svs.clients:
  153. int m_nClientSlot;
  154. // entity index of this client (different from clientSlot+1 in HLTV and Replay mode):
  155. int m_nEntityIndex;
  156. int m_UserID; // identifying number on server
  157. char m_Name[MAX_PLAYER_NAME_LENGTH]; // for printing to other people
  158. char m_GUID[SIGNED_GUID_LEN + 1]; // the clients CD key
  159. CSteamID m_SteamID; // This is valid when the client is authenticated
  160. uint32 m_nFriendsID; // client's friends' ID
  161. char m_FriendsName[MAX_PLAYER_NAME_LENGTH];
  162. KeyValues *m_ConVars; // stores all client side convars
  163. bool m_bConVarsChanged; // true if convars updated and not changes process yet
  164. bool m_bInitialConVarsSet; // Has the client sent their initial set of convars
  165. bool m_bSendServerInfo; // true if we need to send server info packet to start connect
  166. CBaseServer *m_Server; // pointer to server object
  167. bool m_bIsHLTV; // if this a HLTV proxy ?
  168. #if defined( REPLAY_ENABLED )
  169. bool m_bIsReplay; // if this is a Replay proxy ?
  170. #endif
  171. int m_clientChallenge; // client's challenge he sent us, we use to auth replies
  172. // Client sends this during connection, so we can see if
  173. // we need to send sendtable info or if the .dll matches
  174. CRC32_t m_nSendtableCRC;
  175. // a client can have couple of cutomized files distributed to all other players
  176. CustomFile_t m_nCustomFiles[MAX_CUSTOM_FILES];
  177. int m_nFilesDownloaded; // counter of how many files we downloaded from this client
  178. //===== NETWORK ============
  179. INetChannel *m_NetChannel; // The client's net connection.
  180. int m_nSignonState; // connection state
  181. int m_nDeltaTick; // -1 = no compression. This is where the server is creating the
  182. // compressed info from.
  183. int m_nStringTableAckTick; // Highest tick acked for string tables (usually m_nDeltaTick, except when it's -1)
  184. int m_nSignonTick; // tick the client got his signon data
  185. CSmartPtr<CFrameSnapshot,CRefCountAccessorLongName> m_pLastSnapshot; // last send snapshot
  186. CFrameSnapshot *m_pBaseline; // current entity baselines as a snapshot
  187. int m_nBaselineUpdateTick; // last tick we send client a update baseline signal or -1
  188. CBitVec<MAX_EDICTS> m_BaselinesSent; // baselines sent with last update
  189. int m_nBaselineUsed; // 0/1 toggling flag, singaling client what baseline to use
  190. // This is used when we send out a nodelta packet to put the client in a state where we wait
  191. // until we get an ack from them on this packet.
  192. // This is for 3 reasons:
  193. // 1. A client requesting a nodelta packet means they're screwed so no point in deluging them with data.
  194. // Better to send the uncompressed data at a slow rate until we hear back from them (if at all).
  195. // 2. Since the nodelta packet deletes all client entities, we can't ever delta from a packet previous to it.
  196. // 3. It can eat up a lot of CPU on the server to keep building nodelta packets while waiting for
  197. // a client to get back on its feet.
  198. int m_nForceWaitForTick;
  199. bool m_bFakePlayer; // JAC: This client is a fake player controlled by the game DLL
  200. bool m_bReportFakeClient; // Should this fake client be reported
  201. bool m_bReceivedPacket; // true, if client received a packet after the last send packet
  202. bool m_bFullyAuthenticated;
  203. // Time when last name change was applied
  204. double m_fTimeLastNameChange;
  205. bool m_bPlayerNameLocked;
  206. // Does this client have a name change that is pending?
  207. // (Their 'name' convar differs from our value for their client name.)
  208. char m_szPendingNameChange[MAX_PLAYER_NAME_LENGTH];
  209. // The datagram is written to after every frame, but only cleared
  210. // when it is sent out to the client. overflow is tolerated.
  211. // Time when we should send next world state update ( datagram )
  212. double m_fNextMessageTime;
  213. // Default time to wait for next message
  214. float m_fSnapshotInterval;
  215. enum
  216. {
  217. SNAPSHOT_SCRATCH_BUFFER_SIZE = 160000,
  218. };
  219. unsigned int m_SnapshotScratchBuffer[ SNAPSHOT_SCRATCH_BUFFER_SIZE / 4 ];
  220. private:
  221. void StartTrace( bf_write &msg );
  222. void EndTrace( bf_write &msg );
  223. int m_iTracing; // 0 = not active, 1 = active for this frame, 2 = forced active
  224. CNetworkStatTrace m_Trace;
  225. };
  226. #endif // BASECLIENT_H