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.

303 lines
13 KiB

  1. //====== Copyright (c), Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef GCBASE_H
  7. #define GCBASE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "gamecoordinator/igamecoordinator.h"
  12. #include "gamecoordinator/igamecoordinatorhost.h"
  13. #include "tier1/utlallocation.h"
  14. #include "gcmsg.h"
  15. #include "jobmgr.h"
  16. #include "tier1/thash.h"
  17. #include "tier1/utlsortvector.h"
  18. #include "http.h"
  19. #include "language.h"
  20. #include "accountdetails.h"
  21. class CGCMsgGetSystemStatsResponse;
  22. namespace GCSDK
  23. {
  24. class CGCSession;
  25. class CGCUserSession;
  26. class CGCGSSession;
  27. class CGCSharedObjectCache;
  28. class CSharedObject;
  29. class CAccountDetails;
  30. struct PackageLicense_t
  31. {
  32. uint32 m_unPackageID;
  33. RTime32 m_rtimeCreated;
  34. };
  35. class CGCBase : public IGameCoordinator
  36. {
  37. public:
  38. CGCBase( );
  39. virtual ~CGCBase();
  40. // Hooks to extend the base behaviors of the IGameCoordinator interface
  41. virtual bool OnInit() { return true; }
  42. virtual bool OnMainLoopOncePerFrame( CLimitTimer &limitTimer ) { return false; }
  43. virtual bool OnMainLoopUntilFrameCompletion( CLimitTimer &limitTimer ) { return false; }
  44. virtual void OnUninit() {}
  45. // returns true if this function handled the message
  46. virtual bool OnMessageFromClient( const CSteamID & senderID, uint32 unMsgType, void *pubData, uint32 cubData ) { return false; }
  47. virtual void OnValidate( CValidator &validator, const char *pchName ) {}
  48. virtual const char *LocalizeToken( const char *pchToken, ELanguage eLanguage, bool bReturnTokenIfNotFound = true ) { return ""; }
  49. // Life cycle management functions
  50. // Called to do any yielding initialization work before reporting as fully operational
  51. virtual bool BYieldingFinishStartup() = 0;
  52. // Called to do any yielding work immediately after becoming full operational
  53. virtual bool BYieldingPostStartup() = 0;
  54. // Call to report that we're fully operational
  55. void SetStartupComplete( bool bSuccess );
  56. // Called to do any yielding work before reporting as ready to shutdown
  57. virtual void YieldingGracefulShutdown() = 0;
  58. virtual CGCUserSession *CreateUserSession( const CSteamID & steamID, CGCSharedObjectCache *pSOCache ) const;
  59. virtual CGCGSSession *CreateGSSession( const CSteamID & steamID, CGCSharedObjectCache *pSOCache, uint32 unServerAddr, uint16 usServerPort ) const;
  60. virtual void YieldingSessionStartPlaying( CGCUserSession *pSession ) {}
  61. virtual void YieldingSessionStopPlaying( CGCUserSession *pSession ) {}
  62. virtual void YieldingSessionStartServer( CGCGSSession *pSession ) {}
  63. virtual void YieldingSessionStopServer( CGCGSSession *pSession ) {}
  64. virtual void YieldingSOCacheLoaded( CGCSharedObjectCache *pSOCache );
  65. virtual void YieldingPreTestSetup() {}
  66. // cache management
  67. CGCSharedObjectCache *YieldingGetLockedSOCache( const CSteamID &steamID );
  68. CGCSharedObjectCache *YieldingFindOrLoadSOCache( const CSteamID &steamID );
  69. CGCSharedObjectCache *FindSOCache( const CSteamID & steamID ); // non-yielding, but may return NULL if the cache exists but is not loaded
  70. bool UnloadUnusedCaches( uint32 unMaxCacheCount, CLimitTimer *pLimitTimer = NULL );
  71. void YieldingReloadCache( CGCSharedObjectCache *pSOCache );
  72. virtual CGCSharedObjectCache *CreateSOCache( const CSteamID &steamID );
  73. CGCUserSession *YieldingGetLockedUserSession( const CSteamID & steamID );
  74. CGCUserSession *FindUserSession( const CSteamID & steamID ) const;
  75. CGCGSSession *YieldingGetLockedGSSession( const CSteamID & steamID );
  76. CGCGSSession *YieldingFindOrCreateGSSession( const CSteamID & steamID, uint32 unServerAddr, uint16 usServerPort, const uint8 *pubVarData, uint32 cubVarData );
  77. CGCGSSession *FindGSSession( const CSteamID & steamID ) const;
  78. CGCSession *YieldingRequestSession( const CSteamID & steamID );
  79. bool BYieldingIsOnline( const CSteamID & steamID );
  80. bool BYieldingSendHTTPRequest( CHTTPRequest *pRequest, CHTTPResponse *pResponse );
  81. bool BYieldingSendHTTPRequest( CHTTPRequest *pRequest, KeyValues *pkvResponse );
  82. bool BSendWebApiRegistration();
  83. int GetSOCacheCount() const;
  84. #ifdef DEBUG
  85. bool IsSOCached( CSharedObject *pObj, int nTypeID );
  86. #endif
  87. int GetUserSessionCount() const;
  88. int GetGSSessionCount() const;
  89. void SetIsShuttingDown( bool bIsShuttingDown ) { m_bIsShuttingDown = true; }
  90. bool GetIsShuttingDown() const { return m_bIsShuttingDown; }
  91. // Iterate over sessions
  92. // WARNING: Don't yield between GetFirst*/GetNext*. Use caution when using
  93. // these any time you might have tens of thousands of sessions to iterate through.
  94. CGCUserSession **GetFirstUserSession() { return m_hashUserSessions.PvRecordFirst(); }
  95. CGCUserSession **GetNextUserSession( CGCUserSession **pUserSession ) { return m_hashUserSessions.PvRecordNext( pUserSession ); }
  96. CGCGSSession **GetFirstGSSession() { return m_hashGSSessions.PvRecordFirst(); }
  97. CGCGSSession **GetNextGSSession( CGCGSSession **pGSSession ) { return m_hashGSSessions.PvRecordNext( pGSSession ); }
  98. typedef CUtlSortVector< CGCGSSession *, CUtlSortVectorDefaultLess< CGCGSSession * >, CCopyableUtlVector< CGCGSSession * > > CGCGSSessionSortedVector_t;
  99. CGCGSSessionSortedVector_t const *GetGSSessionVectorByType( int serverType );
  100. // This can cause the server pointer to change between lists, call it here
  101. void SetGSServerType( CGCGSSession *pGSSession, int serverType );
  102. AppId_t GetAppID() const { return m_unAppID; }
  103. bool BIsStartupComplete() const { return m_bStartupComplete; }
  104. CJobMgr &GetJobMgr() { return m_JobMgr; }
  105. CSteamID YieldingGuessSteamIDFromInput( const char *pchInput );
  106. bool BYieldingRecordSupportAction( const CSteamID & actorID, const CSteamID & targetID, const char *pchData, const char *pchNote );
  107. void PostAlert( EAlertType eAlertType, bool bIsCritical, const char *pchAlertText, const CUtlVector< CUtlString > *pvecExtendedInfo = NULL, bool bAlsoSpew = true );
  108. CAccountDetails *YieldingGetAccountDetails( const CSteamID & steamID );
  109. bool BYieldingGetAccountLicenses( const CSteamID & steamID, CUtlVector< PackageLicense_t > & vecPackages );
  110. bool BYieldingLookupAccount( EAccountFindType eFindType, const char *pchInput, CUtlVector< CSteamID > *prSteamIDs );
  111. bool BYieldingAddFreeLicense( const CSteamID & steamID, uint32 unPackageID, uint32 unIPPublic = 0, const char *pchStoreCountryCode = NULL );
  112. bool BSendGCMsgToClient( const CSteamID & steamIDTarget, const CGCMsgBase& msg );
  113. bool BSendGCMsgToClient( const CSteamID & steamIDTarget, const IProtoBufMsg& msg );
  114. bool BSendSystemMessage( const CGCMsgBase& msg );
  115. bool BSendSystemMessage( const IProtoBufMsg& msg );
  116. bool BSendGCInterMessage( AppId_t unAppID, const IProtoBufMsg &msg );
  117. bool BReplyToMessage( CGCMsgBase &msgOut, const CGCMsgBase &msgIn );
  118. bool BReplyToMessage( IProtoBufMsg &msgOut, const IProtoBufMsg &msgIn );
  119. const char *GetPath() const { return m_sPath; }
  120. virtual const char *GetSteamAPIKey();
  121. void QueueStartPlaying( const CSteamID & steamID, const CSteamID & gsSteamID, uint32 unServerAddr, uint16 usServerPort, const uint8 *pubVarData, uint32 cubVarData );
  122. void YieldingExecuteNextStartPlaying();
  123. bool BIsInLogonSurge() const;
  124. void YieldingStopPlaying( const CSteamID & steamID );
  125. void YieldingStartGameserver( const CSteamID & steamID, uint32 unServerAddr, uint16 usServerPort, const uint8 *pubVarData, uint32 cubVarData );
  126. void YieldingStopGameserver( const CSteamID & steamID );
  127. bool BIsSOCacheBeingLoaded( const CSteamID & steamID ) const { return m_rbtreeSOCachesBeingLoaded.Find( steamID ) != m_rbtreeSOCachesBeingLoaded.InvalidIndex(); }
  128. bool BYieldingLockSteamID( const CSteamID &steamID );
  129. bool BYieldingLockSteamIDPair( const CSteamID &steamIDA, const CSteamID &steamIDB );
  130. bool BLockSteamIDImmediate( const CSteamID &steamID );
  131. void UnlockSteamID( const CSteamID &steamID );
  132. bool IsSteamIDLocked( const CSteamID &steamID );
  133. bool IsSteamIDLockedByJob( const CSteamID &steamID, const CJob *pJob );
  134. bool IsSteamIDUnlockedOrLockedByCurJob( const CSteamID &steamID );
  135. CJob *PJobHoldingLock( const CSteamID &steamID );
  136. const CLock *FindLock( const CSteamID &steamID );
  137. void DumpLocks( bool bFull, int nMax = 10 );
  138. void DumpJobs( int nMax ) const;
  139. virtual void Dump() const;
  140. void VerifySOCacheLRU();
  141. void SetProfilingEnabled( bool bEnabled );
  142. void SetDumpVprofImbalances( bool bEnabled );
  143. bool GetVprofImbalances();
  144. bool YieldingWritebackDirtyCaches( uint32 unSecondToDelayWrite );
  145. void AddCacheToWritebackQueue( CGCSharedObjectCache *pSOCache );
  146. bool BYieldingRetrieveCacheVersion( CGCSharedObjectCache *pSOCache );
  147. void AddCacheToVersionChangedList( CGCSharedObjectCache *pSOCache );
  148. const char *GetCDNURL() const;
  149. struct GCMemcachedBuffer_t
  150. {
  151. const void *m_pubData;
  152. int m_cubData;
  153. };
  154. struct GCMemcachedGetResult_t
  155. {
  156. bool m_bKeyFound; // true if the key was found
  157. CUtlAllocation m_bufValue; // the value of the key
  158. };
  159. // Memcached access
  160. bool BMemcachedSet( const char *pKey, const ::google::protobuf::Message &protoBufObj );
  161. bool BMemcachedDelete( const char *pKey );
  162. bool BYieldingMemcachedGet( const char *pKey, ::google::protobuf::Message &protoBufObj );
  163. bool BMemcachedSet( const CUtlString &strKey, const CUtlBuffer &buf );
  164. bool BMemcachedSet( const CUtlVector<CUtlString> &vecKeys, const CUtlVector<GCMemcachedBuffer_t> &vecValues );
  165. bool BMemcachedDelete( const CUtlString &strKey );
  166. bool BMemcachedDelete( const CUtlVector<CUtlString> &vecKeys );
  167. bool BYieldingMemcachedGet( const CUtlString &strKey, GCMemcachedGetResult_t &result );
  168. bool BYieldingMemcachedGet( const CUtlVector<CUtlString> &vecKeys, CUtlVector<GCMemcachedGetResult_t> &vecResults );
  169. // IP location
  170. bool BYieldingGetIPLocations( CUtlVector<uint32> &vecIPs, CUtlVector<CIPLocationInfo> &infos );
  171. // Stats
  172. virtual void SystemStats_Update( CGCMsgGetSystemStatsResponse &msgStats );
  173. protected:
  174. virtual bool BYieldingLoadSOCache( CGCSharedObjectCache *pSOCache );
  175. void RemoveSOCache( const CSteamID & steamID );
  176. void AddCacheToLRU( CGCSharedObjectCache * pSOCache );
  177. void RemoveCacheFromLRU( CGCSharedObjectCache * pSOCache );
  178. void SetStartupComplete() { m_bStartupComplete = true; }
  179. private:
  180. static void AssertCallbackFunc( const char *pchFile, int nLine, const char *pchMessage );
  181. void UpdateSOCacheVersions();
  182. // this is called from ExecuteNextStartPlaying and nowhere else
  183. void YieldingStartPlaying( const CSteamID & steamID, const CSteamID & gsSteamID, uint32 unServerAddr, uint16 usServerPort, CUtlBuffer *pVarData );
  184. // Base behaviors of the IGameCoordinator interface. These are not overridable.
  185. // They each call the On* version below, which is overridable by subclasses
  186. virtual bool BInit( AppId_t unAppID, const char *pchAppPath, IGameCoordinatorHost *pHost );
  187. virtual bool BMainLoopOncePerFrame( uint64 ulLimitMicroseconds );
  188. virtual bool BMainLoopUntilFrameCompletion( uint64 ulLimitMicroseconds );
  189. virtual void Shutdown();
  190. virtual void Uninit();
  191. virtual void MessageFromClient( const CSteamID & senderID, uint32 unMsgType, void *pubData, uint32 cubData );
  192. virtual void Validate( CValidator &validator, const char *pchName );
  193. virtual void SQLResults( GID_t gidContextID );
  194. // profiling
  195. bool m_bStartProfiling;
  196. bool m_bStopProfiling;
  197. bool m_bDumpVprofImbalances;
  198. // local job handling
  199. CJobMgr m_JobMgr;
  200. CGCWGJobMgr m_wgJobMgr;
  201. // session tracking
  202. CTHash<CGCUserSession *, uint64> m_hashUserSessions;
  203. CTHash<CGCGSSession *, uint64> m_hashGSSessions;
  204. typedef CUtlMap< int, CGCGSSessionSortedVector_t > CGCGSSessionServerTypeMap_t;
  205. CGCGSSessionServerTypeMap_t m_GSSessionsByTypeMap;
  206. CUtlMap< uint64, CGCGSSession*, int > m_mapGSSessionsByNetAddress;
  207. // Shared object caches
  208. CUtlMap<CSteamID, CGCSharedObjectCache *, int> m_mapSOCache;
  209. CUtlVector< CGCSharedObjectCache * >m_vecCacheWritebacks;
  210. CUtlLinkedList< CSteamID, uint32> m_listCachesToUnload;
  211. CUtlRBTree<CSteamID, int > m_rbtreeSOCachesBeingLoaded;
  212. CUtlRBTree<CSteamID, int > m_rbtreeSOCachesWithDirtyVersions;
  213. // steamID locks
  214. CTHash<CLock, CSteamID> m_hashSteamIDLocks;
  215. // Account Details
  216. CAccountDetailsManager m_AccountDetailsManager;
  217. // State
  218. AppId_t m_unAppID;
  219. CUtlString m_sPath;
  220. IGameCoordinatorHost *m_pHost;
  221. bool m_bStartupComplete;
  222. bool m_bIsShuttingDown;
  223. struct StartPlayingWork_t
  224. {
  225. CSteamID m_steamID;
  226. CSteamID m_gsSteamID;
  227. uint32 m_unServerAddr;
  228. uint16 m_usServerPort;
  229. CUtlBuffer *m_pVarData;
  230. };
  231. CUtlLinkedList< StartPlayingWork_t, int > m_llStartPlaying;
  232. int m_nStartPlayingJobCount;
  233. // URL to use for our app's CDN'd images
  234. mutable CUtlString m_sCDNURL;
  235. };
  236. extern CGCBase *GGCBase();
  237. EResult YieldingSendWebAPIRequest( CSteamAPIRequest &request, KeyValues *pKVResponse, CUtlString &errMsg, bool b200MeansSuccess );
  238. } // namespace GCSDK
  239. #endif // GCBASE_H