Counter Strike : Global Offensive Source Code
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.

363 lines
13 KiB

  1. //========= Copyright � 1996-2005, 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. #include "tier1/utlarray.h"
  25. #include "netmessages.h"
  26. // class CClientFrame;
  27. class CBaseServer;
  28. class CClientFrame;
  29. struct player_info_s;
  30. class CFrameSnapshot;
  31. class CEventInfo;
  32. class CCommand;
  33. struct NetMessageCvar_t;
  34. class CHLTVServer;
  35. struct Spike_t
  36. {
  37. public:
  38. Spike_t() :
  39. m_nBits( 0 )
  40. {
  41. m_szDesc[ 0 ] = 0;
  42. }
  43. char m_szDesc[ 64 ];
  44. int m_nBits;
  45. };
  46. class CNetworkStatTrace
  47. {
  48. public:
  49. CNetworkStatTrace() :
  50. m_nMinWarningBytes( 0 ), m_nStartBit( 0 ), m_nCurBit( 0 )
  51. {
  52. }
  53. int m_nMinWarningBytes;
  54. int m_nStartBit;
  55. int m_nCurBit;
  56. CUtlVector< Spike_t > m_Records;
  57. };
  58. class CBaseClient : public IGameEventListener2, public IClient
  59. {
  60. typedef struct CustomFile_s
  61. {
  62. CRC32_t crc; //file CRC
  63. unsigned int reqID; // download request ID
  64. } CustomFile_t;
  65. public:
  66. CBaseClient();
  67. virtual ~CBaseClient();
  68. public:
  69. int GetPlayerSlot() const { return m_nClientSlot; };
  70. int GetUserID() const { return m_UserID; };
  71. const USERID_t GetNetworkID() const;
  72. const char *GetClientName() const { return m_Name; };
  73. INetChannel *GetNetChannel() { return m_NetChannel; };
  74. IServer *GetServer() { return (IServer*)m_Server; };
  75. CHLTVServer *GetHltvServer();
  76. CHLTVServer *GetAnyConnectedHltvServer();
  77. const char *GetUserSetting(const char *cvar) const;
  78. const char *GetNetworkIDString() const;
  79. uint64 GetClientXuid() const;
  80. const char *GetFriendsName() const { return m_FriendsName; }
  81. void UpdateName( const char *pszDefault );
  82. virtual void Connect(const char * szName, int nUserID, INetChannel *pNetChannel, bool bFakePlayer, CrossPlayPlatform_t clientPlatform, const CMsg_CVars *pVecCvars = NULL );
  83. virtual void Inactivate( void )OVERRIDE;
  84. virtual void Reconnect( void )OVERRIDE;
  85. virtual void Disconnect( const char *reason ) OVERRIDE;
  86. virtual bool CheckConnect( void );
  87. virtual bool ChangeSplitscreenUser( int nSplitScreenUserSlot );
  88. virtual void SetRate( int nRate, bool bForce );
  89. virtual int GetRate( void ) const;
  90. virtual void SetUpdateRate( float fUpdateRate, bool bForce ); // override;
  91. virtual float GetUpdateRate( void ) const; // override;
  92. virtual void Clear( void );
  93. virtual void DemoRestart( void ); // called when client started demo recording
  94. virtual int GetMaxAckTickCount() const;
  95. virtual bool ExecuteStringCommand( const char *s );
  96. virtual bool SendNetMsg( INetMessage &msg, bool bForceReliable = false, bool bVoice = false );
  97. virtual void ClientPrintf ( PRINTF_FORMAT_STRING const char *fmt, ...) FMTFUNCTION( 2, 3 );
  98. virtual bool IsConnected( void ) const { return m_nSignonState >= SIGNONSTATE_CONNECTED; };
  99. virtual bool IsSpawned( void ) const { return m_nSignonState >= SIGNONSTATE_NEW; };
  100. virtual bool IsActive( void ) const { return m_nSignonState == SIGNONSTATE_FULL; };
  101. virtual bool IsFakeClient( void ) const { return m_bFakePlayer; };
  102. virtual bool IsHLTV( void ) const { return m_bIsHLTV; }
  103. #if defined( REPLAY_ENABLED )
  104. virtual bool IsReplay( void ) const { return m_bIsReplay; }
  105. #else
  106. virtual bool IsReplay( void ) const { return false; }
  107. #endif // REPLAY_ENABLED
  108. // Is an actual human player or splitscreen player (not a bot and not a HLTV slot)
  109. virtual bool IsHumanPlayer() const;
  110. virtual bool IsHearingClient( int index ) const { return false; };
  111. virtual bool IsProximityHearingClient( int index ) const { return false; };
  112. virtual bool IsLowViolenceClient( void ) const { return m_bLowViolence; }
  113. virtual void SetMaxRoutablePayloadSize( int nMaxRoutablePayloadSize );
  114. virtual bool IsSplitScreenUser( void ) const { return m_bSplitScreenUser; }
  115. virtual CrossPlayPlatform_t GetClientPlatform() const { return m_ClientPlatform; }
  116. public: // Message Handlers
  117. bool NETMsg_Tick( const CNETMsg_Tick& msg );
  118. bool NETMsg_StringCmd( const CNETMsg_StringCmd& msg );
  119. bool NETMsg_SignonState( const CNETMsg_SignonState& msg );
  120. virtual bool NETMsg_PlayerAvatarData( const CNETMsg_PlayerAvatarData& msg );
  121. virtual bool NETMsg_SetConVar( const CNETMsg_SetConVar& msg );
  122. virtual bool CLCMsg_ClientInfo( const CCLCMsg_ClientInfo& msg );
  123. virtual bool CLCMsg_Move( const CCLCMsg_Move& msg ) { Assert( 0 ); return true; }
  124. virtual bool CLCMsg_VoiceData( const CCLCMsg_VoiceData& msg ) { Assert( 0 ); return true; }
  125. bool CLCMsg_BaselineAck( const CCLCMsg_BaselineAck& msg );
  126. virtual bool CLCMsg_ListenEvents( const CCLCMsg_ListenEvents& msg );
  127. virtual bool CLCMsg_RespondCvarValue( const CCLCMsg_RespondCvarValue& msg ) { Assert( 0 ); return true; }
  128. bool CLCMsg_LoadingProgress( const CCLCMsg_LoadingProgress& msg );
  129. bool CLCMsg_SplitPlayerConnect( const CCLCMsg_SplitPlayerConnect& msg );
  130. virtual bool CLCMsg_FileCRCCheck( const CCLCMsg_FileCRCCheck& msg ) { Assert( 0 ); return true; }
  131. virtual bool CLCMsg_CmdKeyValues( const CCLCMsg_CmdKeyValues& msg );
  132. virtual bool CLCMsg_HltvReplay( const CCLCMsg_HltvReplay &msg ) { return false; }
  133. virtual bool SVCMsg_UserMessage( const CSVCMsg_UserMessage &msg ) { return true; }
  134. enum
  135. {
  136. NETMSG_Tick,
  137. NETMSG_StringCmd,
  138. NETMSG_SetConVar,
  139. NETMSG_SignonState,
  140. NETMSG_ClientInfo,
  141. NETMSG_Move,
  142. NETMSG_VoiceData,
  143. NETMSG_BaselineAck,
  144. NETMSG_ListenEvents,
  145. NETMSG_RespondCvarValue,
  146. NETMSG_SplitPlayerConnect,
  147. NETMSG_FileCRCCheck,
  148. NETMSG_LoadingProgress,
  149. NETMSG_CmdKeyValues,
  150. NETMSG_PlayerAvatarData,
  151. NETMSG_HltvReplay,
  152. NETMSG_UserMessage,
  153. NETMSG_Max
  154. };
  155. CUtlArray< CNetMessageBinder, NETMSG_Max > m_NetMessages;
  156. virtual void ConnectionStart(INetChannel *chan) OVERRIDE;
  157. virtual void ConnectionStop()OVERRIDE;
  158. public: // IGameEventListener
  159. virtual void FireGameEvent( IGameEvent *event ) OVERRIDE { FireGameEvent( event, false ); }
  160. void FireGameEvent( IGameEvent *event, bool bPassthrough );
  161. int m_nDebugID;
  162. virtual int GetEventDebugID( void );
  163. public:
  164. virtual bool UpdateAcknowledgedFramecount(int tick);
  165. virtual bool ShouldSendMessages( void );
  166. virtual void UpdateSendState( void );
  167. void ForceFullUpdate( void ) { UpdateAcknowledgedFramecount(-1); }
  168. virtual bool FillUserInfo( player_info_s &userInfo );
  169. virtual void UpdateUserSettings();
  170. virtual void WriteGameSounds(bf_write &buf, int nMaxSounds);
  171. virtual CClientFrame *GetDeltaFrame( int nTick );
  172. virtual bool SendSnapshot( CClientFrame *pFrame );
  173. virtual bool SendServerInfo( void );
  174. virtual void OnSteamServerLogonSuccess( uint32 externalIP );
  175. virtual bool SendSignonData( void );
  176. virtual void SpawnPlayer( void );
  177. virtual void ActivatePlayer( void );
  178. virtual void SetName( const char * name );
  179. virtual void SetUserCVar( const char *cvar, const char *value);
  180. virtual void FreeBaselines();
  181. virtual bool IgnoreTempEntity( CEventInfo *event );
  182. void SetSteamID( const CSteamID &steamID );
  183. int GetSignonState() const { return m_nSignonState; }
  184. void SetSignonState( int nState );
  185. bool IsTracing() const;
  186. void SetTraceThreshold( int nThreshold );
  187. void TraceNetworkData( bf_write &msg, PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 3, 4 );
  188. void TraceNetworkMsg( int nBits, PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 3, 4 );
  189. bool IsFullyAuthenticated( void ) { return m_bFullyAuthenticated; }
  190. void SetFullyAuthenticated( void ) { m_bFullyAuthenticated = true; }
  191. void SplitScreenDisconnect( const CCommand &args );
  192. void DisconnectSplitScreenUser( CBaseClient *pSplitClient );
  193. void ApplyConVars( const CMsg_CVars& list, bool bCreateIfNotExisting );
  194. void FillSignOnFullServerInfo( class CNETMsg_SignonState_t& state );
  195. bool IsSplitScreenPartner( const CBaseClient *pOther ) const;
  196. virtual IClient *GetSplitScreenOwner() { return m_pAttachedTo; }
  197. virtual int GetNumPlayers();
  198. virtual bool StartHltvReplay( const HltvReplayParams_t &params ) OVERRIDE { return false; } // not implemented for most clients
  199. virtual void StopHltvReplay() OVERRIDE { }
  200. virtual int GetHltvReplayDelay() OVERRIDE { return 0; }
  201. virtual bool CanStartHltvReplay() OVERRIDE { return false; }
  202. virtual void ResetReplayRequestTime() OVERRIDE { }
  203. virtual CBaseClient *GetPropCullClient() { return this; }
  204. void OverrideSignonStateTransparent( int nState ){ m_nSignonState = nState; }
  205. protected:
  206. virtual bool ProcessSignonStateMsg(int state, int spawncount);
  207. virtual void PerformDisconnection( const char *pReason );
  208. void OnPlayerAvatarDataChanged();
  209. private:
  210. void OnRequestFullUpdate( char const *pchReason );
  211. int GetAvailableSplitScreenSlot() const;
  212. void SendFullConnectEvent();
  213. public:
  214. // One of the subservient split screen users?
  215. bool m_bSplitScreenUser;
  216. bool m_bSplitAllowFastDisconnect;
  217. int m_nSplitScreenPlayerSlot;
  218. CBaseClient *m_SplitScreenUsers[ MAX_SPLITSCREEN_CLIENTS ];
  219. CBaseClient *m_pAttachedTo; // If this is a split screen user, this is the "master"
  220. bool m_bSplitPlayerDisconnecting;
  221. // Array index in svs.clients:
  222. int m_nClientSlot;
  223. // entity index of this client (different from clientSlot+1 in HLTV and Replay mode):
  224. int m_nEntityIndex;
  225. int m_UserID; // identifying number on server
  226. char m_Name[MAX_PLAYER_NAME_LENGTH]; // for printing to other people
  227. char m_GUID[SIGNED_GUID_LEN + 1]; // the clients CD key
  228. CNETMsg_PlayerAvatarData_t m_msgAvatarData; // Client avatar
  229. CSteamID m_SteamID; // This is valid when the client is authenticated
  230. uint32 m_nFriendsID; // client's friends' ID
  231. char m_FriendsName[MAX_PLAYER_NAME_LENGTH];
  232. KeyValues *m_ConVars; // stores all client side convars
  233. bool m_bConVarsChanged; // true if convars updated and not changes process yet
  234. bool m_bSendServerInfo; // true if we need to send server info packet to start connect
  235. CBaseServer *m_Server; // pointer to server object
  236. bool m_bIsHLTV; // if this a HLTV proxy ?
  237. CHLTVServer *m_pHltvSlaveServer;
  238. #if defined( REPLAY_ENABLED )
  239. bool m_bIsReplay; // if this is a Replay proxy ?
  240. #endif
  241. // Client sends this during connection, so we can see if
  242. // we need to send sendtable info or if the .dll matches
  243. CRC32_t m_nSendtableCRC;
  244. // a client can have couple of cutomized files distributed to all other players
  245. CustomFile_t m_nCustomFiles[MAX_CUSTOM_FILES];
  246. int m_nFilesDownloaded; // counter of how many files we downloaded from this client
  247. //===== NETWORK ============
  248. INetChannel *m_NetChannel; // The client's net connection.
  249. private:
  250. int m_nSignonState; // connection state
  251. public:
  252. int m_nDeltaTick; // -1 = no compression. This is where the server is creating the
  253. // compressed info from.
  254. int m_nStringTableAckTick; // Highest tick acked for string tables (usually m_nDeltaTick, except when it's -1)
  255. int m_nSignonTick; // tick the client got his signon data
  256. CSmartPtr<CFrameSnapshot,CRefCountAccessorLongName> m_pLastSnapshot; // last send snapshot
  257. int m_nLoadingProgress; // 0..100 progress, only valid during loading
  258. CFrameSnapshot *m_pBaseline; // current entity baselines as a snapshot
  259. int m_nBaselineUpdateTick; // last tick we send client a update baseline signal or -1
  260. CBitVec<MAX_EDICTS> m_BaselinesSent; // baselines sent with last update
  261. int m_nBaselineUsed; // 0/1 toggling flag, singaling client what baseline to use
  262. // This is used when we send out a nodelta packet to put the client in a state where we wait
  263. // until we get an ack from them on this packet.
  264. // This is for 3 reasons:
  265. // 1. A client requesting a nodelta packet means they're screwed so no point in deluging them with data.
  266. // Better to send the uncompressed data at a slow rate until we hear back from them (if at all).
  267. // 2. Since the nodelta packet deletes all client entities, we can't ever delta from a packet previous to it.
  268. // 3. It can eat up a lot of CPU on the server to keep building nodelta packets while waiting for
  269. // a client to get back on its feet.
  270. int m_nForceWaitForTick;
  271. bool m_bFakePlayer; // JAC: This client is a fake player controlled by the game DLL
  272. bool m_bReceivedPacket; // true, if client received a packet after the last send packet
  273. bool m_bLowViolence; // true if client is in low-violence mode (L4D server needs to know)
  274. bool m_bFullyAuthenticated;
  275. // The datagram is written to after every frame, but only cleared
  276. // when it is sent out to the client. overflow is tolerated.
  277. // Time when we should send next world state update ( datagram )
  278. double m_fNextMessageTime;
  279. // Default time to wait for next message
  280. float m_fSnapshotInterval;
  281. CrossPlayPlatform_t m_ClientPlatform;
  282. // Keep these as class members instead of a local variable so that we don't reallocate the
  283. // strings and their buffers every time.
  284. CSVCMsg_TempEntities_t m_tempentsmsg;
  285. CSVCMsg_PacketEntities_t m_packetmsg;
  286. private:
  287. void StartTrace( bf_write &msg );
  288. void EndTrace( bf_write &msg );
  289. CNetworkStatTrace m_Trace;
  290. };
  291. #endif // BASECLIENT_H