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.

241 lines
8.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef GCJOB_H
  7. #define GCJOB_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "gcwebapikey.h"
  12. namespace GCSDK
  13. {
  14. //a free standing utility function that takes in a newly allocated job, and tells the job to start executing. An example of this would be pStore = StartNewJobDelayed( new CFooJob( Params ) );
  15. template < typename T >
  16. inline typename T* StartNewJobDelayed( T* pNewJob )
  17. {
  18. if ( pNewJob )
  19. pNewJob->StartJobDelayed( NULL );
  20. return pNewJob;
  21. }
  22. //-----------------------------------------------------------------------------
  23. // Purpose: Control access to web api accounts so that they can be rate limited/blocked/exempt, etc
  24. //-----------------------------------------------------------------------------
  25. enum EWebAPIAccountLevel
  26. {
  27. eWebAPIAccountLevel_RateLimited = 0, //default, rate limit
  28. eWebAPIAccountLevel_Blocked = 1, //block all requests
  29. eWebAPIAccountLevel_Unlimited = 2, //do not rate limit
  30. eWebAPIAccountLevel_Elevated = 3, //like rate limiting, but at a higher threshold
  31. };
  32. //resets all accounts to the default permission
  33. void WebAPIAccount_ResetAllPermissions();
  34. //called to associate a permission level with an account
  35. void WebAPIAccount_SetPermission( AccountID_t nID, EWebAPIAccountLevel eLevel );
  36. //external calling interface in case we want to use this from a non-WebAPI job
  37. bool WebAPIAccount_BTrackUserAndValidate( AccountID_t nID, uint32 unIP );
  38. //-----------------------------------------------------------------------------
  39. // Purpose: handles a network message job from the client
  40. //-----------------------------------------------------------------------------
  41. class CGCJob : public CJob
  42. {
  43. public:
  44. // Constructor: when overriding job name a static string pointer must be used
  45. CGCJob( CGCBase *pGC, const char *pchJobName = NULL ) : CJob( pGC->GetJobMgr(), pchJobName ), m_pGC( pGC ), m_cHeartbeatsBeforeTimeout( k_cJobHeartbeatsBeforeTimeoutDefault ) {}
  46. // all GC jobs must implement one of these
  47. virtual bool BYieldingRunGCJob( IMsgNetPacket *pNetPacket ) { return false; }
  48. virtual bool BYieldingRunGCJob() { return false; }
  49. virtual EServerType GetServerType() { return k_EServerTypeGC; }
  50. bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CGCMsgBase &msgOut, uint nTimeoutSec, CGCMsgBase *pMsgIn, MsgType_t eMsg );
  51. bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CGCMsgBase &msgOut, uint nTimeoutSec, IMsgNetPacket **ppNetPacket );
  52. bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CProtoBufMsgBase &msgOut, uint nTimeoutSec, CProtoBufMsgBase *pMsgIn, MsgType_t eMsg );
  53. bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CProtoBufMsgBase &msgOut, uint nTimeoutSec, IMsgNetPacket **ppNetPacket );
  54. virtual uint32 CHeartbeatsBeforeTimeout() { return m_cHeartbeatsBeforeTimeout; }
  55. void SetJobTimeout( uint nTimeoutSec ) { m_cHeartbeatsBeforeTimeout = 1 + ( ( nTimeoutSec * k_nMillion - 1 ) / k_cMicroSecJobHeartbeat ); }
  56. protected:
  57. CGCBase *m_pGC;
  58. private:
  59. virtual bool BYieldingRunJobFromMsg( IMsgNetPacket *pNetPacket )
  60. {
  61. return BYieldingRunGCJob( pNetPacket );
  62. }
  63. virtual bool BYieldingRunJob( void *pvStartParam )
  64. {
  65. return BYieldingRunGCJob();
  66. }
  67. uint32 m_cHeartbeatsBeforeTimeout;
  68. };
  69. //This template class is designed to be derived from various job types and provides an adapter for the run from message hook, and handles
  70. //converting it over to an appropriate protobuf message for the caller as well as validating that it parsed properly. It will bail on processing
  71. //the message if the protobuf does not parse.
  72. template < typename TGCJobClass, typename TGCType, typename TProtoMsgClass >
  73. class TProtoMsgJob :
  74. public TGCJobClass
  75. {
  76. public:
  77. typedef CProtoBufMsg< TProtoMsgClass > TProtoMsg;
  78. TProtoMsgJob( TGCType* pGC ) : TGCJobClass( pGC ) {}
  79. virtual bool BYieldingRunJobFromMsg( IMsgNetPacket *pNetPacket ) OVERRIDE
  80. {
  81. TProtoMsg msg( pNetPacket );
  82. if ( !msg.Body().IsInitialized() )
  83. return false;
  84. return BYieldingRunJobFromProtoMsg( msg );
  85. }
  86. virtual bool BYieldingRunJobFromProtoMsg( const TProtoMsg& ProtoMsg ) = 0;
  87. };
  88. //a partial specialization of the proto message job to make it easier to use with GCJob
  89. template < typename TProtoMsgClass >
  90. class CGCProtoJob : public TProtoMsgJob < CGCJob, CGCBase, TProtoMsgClass >
  91. {
  92. public:
  93. CGCProtoJob( CGCBase* pGC ) : TProtoMsgJob( pGC ) {}
  94. //clients need to implement BYieldingRunJobFromProtoMsg
  95. };
  96. //-----------------------------------------------------------------------------
  97. // CGCWGJob - A job invoked from forwarded WG messages
  98. //-----------------------------------------------------------------------------
  99. class CGCWGJob : public CGCJob
  100. {
  101. public:
  102. CGCWGJob( CGCBase *pGCBase );
  103. ~CGCWGJob();
  104. bool BYieldingRunGCJob( IMsgNetPacket * pNetPacket ); // invokes BYieldingRunJobFromRequest
  105. virtual bool BYieldingRunJobFromRequest( KeyValues *pkvRequest, KeyValues *pkvResponse ) = 0;
  106. virtual bool BVerifyParams( const CGCMsg<MsgGCWGRequest_t> & msg, KeyValues *pkvRequest, const WebApiFunc_t * pWebApiFunc );
  107. void SetWebApiFunc( const WebApiFunc_t * pWebApiFunc ) { m_pWebApiFunc = pWebApiFunc; }
  108. void SetErrorMessage( KeyValues *pkvErr, const char *pchErrorMsg, int32 nResult );
  109. protected:
  110. KeyValues *m_pkvResponse;
  111. CUtlBuffer m_bufRequest; // packed binary form of the request
  112. const WebApiFunc_t * m_pWebApiFunc;
  113. // requester auth info, like WGRequestContext
  114. CSteamID m_steamID;
  115. };
  116. //-----------------------------------------------------------------------------
  117. // CGCJobVerifySession - A job that asks steam if a given user is still connected
  118. // and cleans up the session if the user is gone
  119. //-----------------------------------------------------------------------------
  120. class CGCJobVerifySession : public CGCJob
  121. {
  122. public:
  123. CGCJobVerifySession( CGCBase *pGC, const CSteamID &steamID ) : CGCJob( pGC ), m_steamID( steamID ) { }
  124. virtual bool BYieldingRunGCJob();
  125. private:
  126. CSteamID m_steamID;
  127. };
  128. //-----------------------------------------------------------------------------
  129. // CWebAPIJob - A job invoked from a forwarded WebAPI request
  130. //-----------------------------------------------------------------------------
  131. class CWebAPIJob : public CGCJob
  132. {
  133. public:
  134. CWebAPIJob( CGCBase *pGC, EWebAPIOutputFormat eDefaultOutputFormat = k_EWebAPIOutputFormat_JSON );
  135. ~CWebAPIJob();
  136. // Called by jobmgr, and then invokes appropriate run function for specific API version requested
  137. bool BYieldingRunJobFromMsg( IMsgNetPacket * pNetPacket );
  138. // Implemented by each individual WebAPI job, should be declared using BEGIN_WEBAPI_JOB_VERSION_ADAPTERS and related macros.
  139. virtual bool BYieldingRunJobFromAPIRequest( const char *pchInterface, const char *pchMethod, uint32 unVersion, CHTTPRequest *pRequest, CHTTPResponse *pResponse, CWebAPIResponse *pWebAPIResponse ) = 0;
  140. protected:
  141. static void AddLocalizedString( CWebAPIValues *pOutDefn, const char *pchFieldName, const char *pchKeyName, ELanguage eLang, bool bReturnTokenIfNotFound = true );
  142. static void ThreadedEmitFormattedOutputWrapper( CWebAPIResponse *pResponse, EWebAPIOutputFormat eFormat, CUtlBuffer *poutputBuffer, size_t unMaxResultSize, bool *pbResult );
  143. CWebAPIKey m_webAPIKey;
  144. EWebAPIOutputFormat m_eDefaultOutputFormat;
  145. };
  146. #define BEGIN_WEBAPI_JOB_VERSION_ADAPTERS( interface, method ) \
  147. bool BYieldingRunJobFromAPIRequest( const char *pchInterface, const char *pchMethod, uint32 unVersion, CHTTPRequest *pRequest, CHTTPResponse *pResponse, CWebAPIResponse *pWebAPIResponse ) \
  148. { \
  149. if ( Q_strnicmp( pchInterface, interface, Q_strlen( interface ) ) != 0 ) \
  150. { \
  151. AssertMsg2( false, "WebAPIJob recieved request for unexpected interface (got %s, expected %s)!", pchInterface, interface ); \
  152. pResponse->SetStatusCode( k_EHTTPStatusCode500InternalServerError ); \
  153. return false; \
  154. } \
  155. \
  156. if ( Q_stricmp( pchMethod, method ) != 0 ) \
  157. { \
  158. AssertMsg2( false, "WebAPIJob received request fo unexpected method (got %s, expected %s)!", pchMethod, method ); \
  159. pResponse->SetStatusCode( k_EHTTPStatusCode500InternalServerError ); \
  160. return false; \
  161. } \
  162. \
  163. \
  164. bool bFoundVersion = false; \
  165. bool bResult = false; \
  166. switch( unVersion ) \
  167. {
  168. #define WEBAPI_JOB_VERSION_ADAPTER( version, funcname ) \
  169. case version: \
  170. bFoundVersion = true; \
  171. { \
  172. VPROF_BUDGET( #funcname, VPROF_BUDGETGROUP_JOBS_COROUTINES ); \
  173. bResult = this->##funcname( pRequest, pWebAPIResponse ); \
  174. } \
  175. break;
  176. #define WEBAPI_JOB_VERSION_ADAPTER_EXTENDED_ARRAYS( version, funcname ) \
  177. case version: \
  178. bFoundVersion = true; \
  179. pWebAPIResponse->SetExtendedArrays( true ); \
  180. { \
  181. VPROF_BUDGET( #funcname, VPROF_BUDGETGROUP_JOBS_COROUTINES ); \
  182. bResult = this->##funcname( pRequest, pWebAPIResponse ); \
  183. } \
  184. break;
  185. #define END_WEBAPI_JOB_VERSION_ADAPTERS() \
  186. default: \
  187. break; \
  188. } \
  189. AssertMsg3( bFoundVersion, "WebAPIJob for %s/%s received unhandled version %d", pchInterface, pchMethod, unVersion ); \
  190. return bResult; \
  191. }
  192. } // namespace GCSDK
  193. #endif // GCJOB_H