summaryrefslogtreecommitdiff
path: root/public/gcsdk/gcjob.h
diff options
context:
space:
mode:
Diffstat (limited to 'public/gcsdk/gcjob.h')
-rw-r--r--public/gcsdk/gcjob.h241
1 files changed, 241 insertions, 0 deletions
diff --git a/public/gcsdk/gcjob.h b/public/gcsdk/gcjob.h
new file mode 100644
index 0000000..b404531
--- /dev/null
+++ b/public/gcsdk/gcjob.h
@@ -0,0 +1,241 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#ifndef GCJOB_H
+#define GCJOB_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "gcwebapikey.h"
+
+namespace GCSDK
+{
+
+//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 ) );
+template < typename T >
+inline typename T* StartNewJobDelayed( T* pNewJob )
+{
+ if ( pNewJob )
+ pNewJob->StartJobDelayed( NULL );
+ return pNewJob;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Control access to web api accounts so that they can be rate limited/blocked/exempt, etc
+//-----------------------------------------------------------------------------
+
+enum EWebAPIAccountLevel
+{
+ eWebAPIAccountLevel_RateLimited = 0, //default, rate limit
+ eWebAPIAccountLevel_Blocked = 1, //block all requests
+ eWebAPIAccountLevel_Unlimited = 2, //do not rate limit
+ eWebAPIAccountLevel_Elevated = 3, //like rate limiting, but at a higher threshold
+};
+
+//resets all accounts to the default permission
+void WebAPIAccount_ResetAllPermissions();
+//called to associate a permission level with an account
+void WebAPIAccount_SetPermission( AccountID_t nID, EWebAPIAccountLevel eLevel );
+//external calling interface in case we want to use this from a non-WebAPI job
+bool WebAPIAccount_BTrackUserAndValidate( AccountID_t nID, uint32 unIP );
+
+//-----------------------------------------------------------------------------
+// Purpose: handles a network message job from the client
+//-----------------------------------------------------------------------------
+class CGCJob : public CJob
+{
+public:
+ // Constructor: when overriding job name a static string pointer must be used
+ CGCJob( CGCBase *pGC, const char *pchJobName = NULL ) : CJob( pGC->GetJobMgr(), pchJobName ), m_pGC( pGC ), m_cHeartbeatsBeforeTimeout( k_cJobHeartbeatsBeforeTimeoutDefault ) {}
+
+ // all GC jobs must implement one of these
+ virtual bool BYieldingRunGCJob( IMsgNetPacket *pNetPacket ) { return false; }
+ virtual bool BYieldingRunGCJob() { return false; }
+
+ virtual EServerType GetServerType() { return k_EServerTypeGC; }
+
+ bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CGCMsgBase &msgOut, uint nTimeoutSec, CGCMsgBase *pMsgIn, MsgType_t eMsg );
+ bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CGCMsgBase &msgOut, uint nTimeoutSec, IMsgNetPacket **ppNetPacket );
+ bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CProtoBufMsgBase &msgOut, uint nTimeoutSec, CProtoBufMsgBase *pMsgIn, MsgType_t eMsg );
+ bool BYldSendMessageAndGetReply( CSteamID &steamIDTarget, CProtoBufMsgBase &msgOut, uint nTimeoutSec, IMsgNetPacket **ppNetPacket );
+
+ virtual uint32 CHeartbeatsBeforeTimeout() { return m_cHeartbeatsBeforeTimeout; }
+ void SetJobTimeout( uint nTimeoutSec ) { m_cHeartbeatsBeforeTimeout = 1 + ( ( nTimeoutSec * k_nMillion - 1 ) / k_cMicroSecJobHeartbeat ); }
+
+protected:
+ CGCBase *m_pGC;
+
+private:
+ virtual bool BYieldingRunJobFromMsg( IMsgNetPacket *pNetPacket )
+ {
+ return BYieldingRunGCJob( pNetPacket );
+ }
+
+ virtual bool BYieldingRunJob( void *pvStartParam )
+ {
+ return BYieldingRunGCJob();
+ }
+
+ uint32 m_cHeartbeatsBeforeTimeout;
+};
+
+
+//This template class is designed to be derived from various job types and provides an adapter for the run from message hook, and handles
+//converting it over to an appropriate protobuf message for the caller as well as validating that it parsed properly. It will bail on processing
+//the message if the protobuf does not parse.
+template < typename TGCJobClass, typename TGCType, typename TProtoMsgClass >
+class TProtoMsgJob :
+ public TGCJobClass
+{
+public:
+ typedef CProtoBufMsg< TProtoMsgClass > TProtoMsg;
+
+ TProtoMsgJob( TGCType* pGC ) : TGCJobClass( pGC ) {}
+
+ virtual bool BYieldingRunJobFromMsg( IMsgNetPacket *pNetPacket ) OVERRIDE
+ {
+ TProtoMsg msg( pNetPacket );
+ if ( !msg.Body().IsInitialized() )
+ return false;
+
+ return BYieldingRunJobFromProtoMsg( msg );
+ }
+
+ virtual bool BYieldingRunJobFromProtoMsg( const TProtoMsg& ProtoMsg ) = 0;
+};
+
+//a partial specialization of the proto message job to make it easier to use with GCJob
+template < typename TProtoMsgClass >
+class CGCProtoJob : public TProtoMsgJob < CGCJob, CGCBase, TProtoMsgClass >
+{
+public:
+ CGCProtoJob( CGCBase* pGC ) : TProtoMsgJob( pGC ) {}
+ //clients need to implement BYieldingRunJobFromProtoMsg
+};
+
+//-----------------------------------------------------------------------------
+// CGCWGJob - A job invoked from forwarded WG messages
+//-----------------------------------------------------------------------------
+class CGCWGJob : public CGCJob
+{
+public:
+ CGCWGJob( CGCBase *pGCBase );
+ ~CGCWGJob();
+ bool BYieldingRunGCJob( IMsgNetPacket * pNetPacket ); // invokes BYieldingRunJobFromRequest
+ virtual bool BYieldingRunJobFromRequest( KeyValues *pkvRequest, KeyValues *pkvResponse ) = 0;
+ virtual bool BVerifyParams( const CGCMsg<MsgGCWGRequest_t> & msg, KeyValues *pkvRequest, const WebApiFunc_t * pWebApiFunc );
+ void SetWebApiFunc( const WebApiFunc_t * pWebApiFunc ) { m_pWebApiFunc = pWebApiFunc; }
+
+ void SetErrorMessage( KeyValues *pkvErr, const char *pchErrorMsg, int32 nResult );
+
+protected:
+ KeyValues *m_pkvResponse;
+ CUtlBuffer m_bufRequest; // packed binary form of the request
+ const WebApiFunc_t * m_pWebApiFunc;
+
+ // requester auth info, like WGRequestContext
+ CSteamID m_steamID;
+};
+
+
+//-----------------------------------------------------------------------------
+// CGCJobVerifySession - A job that asks steam if a given user is still connected
+// and cleans up the session if the user is gone
+//-----------------------------------------------------------------------------
+class CGCJobVerifySession : public CGCJob
+{
+public:
+ CGCJobVerifySession( CGCBase *pGC, const CSteamID &steamID ) : CGCJob( pGC ), m_steamID( steamID ) { }
+ virtual bool BYieldingRunGCJob();
+
+private:
+ CSteamID m_steamID;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// CWebAPIJob - A job invoked from a forwarded WebAPI request
+//-----------------------------------------------------------------------------
+class CWebAPIJob : public CGCJob
+{
+public:
+ CWebAPIJob( CGCBase *pGC, EWebAPIOutputFormat eDefaultOutputFormat = k_EWebAPIOutputFormat_JSON );
+ ~CWebAPIJob();
+
+ // Called by jobmgr, and then invokes appropriate run function for specific API version requested
+ bool BYieldingRunJobFromMsg( IMsgNetPacket * pNetPacket );
+
+ // Implemented by each individual WebAPI job, should be declared using BEGIN_WEBAPI_JOB_VERSION_ADAPTERS and related macros.
+ virtual bool BYieldingRunJobFromAPIRequest( const char *pchInterface, const char *pchMethod, uint32 unVersion, CHTTPRequest *pRequest, CHTTPResponse *pResponse, CWebAPIResponse *pWebAPIResponse ) = 0;
+
+protected:
+ static void AddLocalizedString( CWebAPIValues *pOutDefn, const char *pchFieldName, const char *pchKeyName, ELanguage eLang, bool bReturnTokenIfNotFound = true );
+ static void ThreadedEmitFormattedOutputWrapper( CWebAPIResponse *pResponse, EWebAPIOutputFormat eFormat, CUtlBuffer *poutputBuffer, size_t unMaxResultSize, bool *pbResult );
+
+ CWebAPIKey m_webAPIKey;
+ EWebAPIOutputFormat m_eDefaultOutputFormat;
+};
+
+
+#define BEGIN_WEBAPI_JOB_VERSION_ADAPTERS( interface, method ) \
+ bool BYieldingRunJobFromAPIRequest( const char *pchInterface, const char *pchMethod, uint32 unVersion, CHTTPRequest *pRequest, CHTTPResponse *pResponse, CWebAPIResponse *pWebAPIResponse ) \
+{ \
+ if ( Q_strnicmp( pchInterface, interface, Q_strlen( interface ) ) != 0 ) \
+{ \
+ AssertMsg2( false, "WebAPIJob recieved request for unexpected interface (got %s, expected %s)!", pchInterface, interface ); \
+ pResponse->SetStatusCode( k_EHTTPStatusCode500InternalServerError ); \
+ return false; \
+} \
+ \
+ if ( Q_stricmp( pchMethod, method ) != 0 ) \
+{ \
+ AssertMsg2( false, "WebAPIJob received request fo unexpected method (got %s, expected %s)!", pchMethod, method ); \
+ pResponse->SetStatusCode( k_EHTTPStatusCode500InternalServerError ); \
+ return false; \
+} \
+ \
+ \
+ bool bFoundVersion = false; \
+ bool bResult = false; \
+ switch( unVersion ) \
+{
+
+#define WEBAPI_JOB_VERSION_ADAPTER( version, funcname ) \
+ case version: \
+ bFoundVersion = true; \
+ { \
+ VPROF_BUDGET( #funcname, VPROF_BUDGETGROUP_JOBS_COROUTINES ); \
+ bResult = this->##funcname( pRequest, pWebAPIResponse ); \
+ } \
+ break;
+
+#define WEBAPI_JOB_VERSION_ADAPTER_EXTENDED_ARRAYS( version, funcname ) \
+ case version: \
+ bFoundVersion = true; \
+ pWebAPIResponse->SetExtendedArrays( true ); \
+ { \
+ VPROF_BUDGET( #funcname, VPROF_BUDGETGROUP_JOBS_COROUTINES ); \
+ bResult = this->##funcname( pRequest, pWebAPIResponse ); \
+ } \
+ break;
+
+#define END_WEBAPI_JOB_VERSION_ADAPTERS() \
+ default: \
+ break; \
+} \
+ AssertMsg3( bFoundVersion, "WebAPIJob for %s/%s received unhandled version %d", pchInterface, pchMethod, unVersion ); \
+ return bResult; \
+}
+
+
+
+
+} // namespace GCSDK
+
+
+#endif // GCJOB_H