csgo-2018-source/common/steamclientpublic.h
2021-07-24 21:11:47 -07:00

476 lines
18 KiB
C++

//========= Copyright © 1996-2004, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef STEAMCLIENTPUBLIC_H
#define STEAMCLIENTPUBLIC_H
#ifdef _WIN32
#pragma once
#endif
//lint -save -e1931 -e1927 -e1924 -e613 -e726
// This header file defines the interface between the calling application and the code that
// knows how to communicate with the connection manager (CM) from the Steam service
// This header file is intended to be portable; ideally this 1 header file plus a lib or dll
// is all you need to integrate the client library into some other tree. So please avoid
// including or requiring other header files if possible. This header should only describe the
// interface layer, no need to include anything about the implementation.
#include "steamtypes.h"
#ifndef NETADR_H
class netadr_t;
#endif
class ICMInterface; // forward declaration
class ICMCallback; // forward declaration
class IVConnCallback; // forward declaration
extern "C" {
ICMInterface * CreateCMInterface( ICMCallback * pCMCallback ); // global function to create an interface object
typedef ICMInterface * (* LPCREATECMINTERFACEPROC)( ICMCallback * ); // typedef for function pointer (for GetProcAddress)
void DestroyCMInterface( ICMInterface * pCMInterface ); // global function to destroy and free an interface object
typedef void (* LPDESTROYCMINTERFACEPROC)( ICMInterface * ); // typedef for function pointer (for GetProcAddress)
}
// General result codes
enum EResult
{
k_EResultOK = 1, // success
k_EResultFail = 2, // generic failure
k_EResultNoConnection = 3, // no/failed network connection
k_EResultNoConnectionRetry = 4, // no/failed network connection, will retry
k_EResultInvalidPassword = 5, // password/ticket is invalid
k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
k_EResultInvalidProtocolVer = 7, // protocol version is incorrect
k_EResultInvalidParam = 8, // a parameter is incorrect
k_EResultFileNotFound = 9, // file was not found
k_EResultBusy = 10, // called method busy - action not taken
k_EResultInvalidState = 11, // called object was in an invalid state
k_EResultInvalidName = 12, // name is invalid
k_EResultInvalidEmail = 13, // email is invalud
k_EResultDuplicateName = 14, // name is not unique
k_EResultAccessDenied = 15, // access is denied
k_EResultTimeout = 16, // operation timed out
};
// Result codes to GSHandleClientDeny/Kick
typedef enum
{
k_EDenyInvalidVersion = 1,
k_EDenyGeneric,
k_EDenyNotLoggedOn,
k_EDenyNoLicense,
k_EDenyCheater,
} EDenyReason;
// Server flags.
const uint k_unServerFlagNone = 0;
const uint k_unServerFlagActive = 1;
const uint k_unServerFlagInsecure = 2;
// Steam universes. Each universe is a self-contained Steam instance.
enum EUniverse
{
k_EUniverseInvalid = 0,
k_EUniversePublic = 1,
k_EUniverseTestPublic = 2,
k_EUniverseInternal = 3,
k_EUniverseMax
};
EUniverse EUniverseFromName( const char * pchUniverseName );
const char * PchNameFromEUniverse( EUniverse eUniverse );
// Steam account types
enum EAccountType
{
k_EAccountTypeInvalid = 0,
k_EAccountTypeIndividual = 1, // single user account
k_EAccountTypeMultiseat = 2, // multiseat (e.g. cybercafe) account
k_EAccountTypeGameServer = 3, // game server account
k_EAccountTypeAnonGameServer = 4, // anonomous game server account
k_EAccountTypePending = 5 // pending
};
#pragma pack( push, 1 )
// Steam ID structure (64 bits total)
class CSteamID
{
public:
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CSteamID( )
{
m_unAccountID = 0;
m_EAccountType = k_EAccountTypeInvalid;
m_EUniverse = k_EUniverseInvalid;
m_unAccountInstance = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : unAccountID - 32-bit account ID
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
CSteamID( uint32 unAccountID, EUniverse eUniverse, EAccountType eAccountType )
{
Set( unAccountID, eUniverse, eAccountType );
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : unAccountID - 32-bit account ID
// unAccountInstance - instance
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
CSteamID( uint32 unAccountID, unsigned int unAccountInstance, EUniverse eUniverse, EAccountType eAccountType )
{
InstancedSet( unAccountID, unAccountInstance, eUniverse, eAccountType );
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : ulSteamID - 64-bit representation of a Steam ID
//-----------------------------------------------------------------------------
CSteamID( uint64 ulSteamID )
{
SetFromUint64( ulSteamID );
}
//-----------------------------------------------------------------------------
// Purpose: Sets parameters for steam ID
// Input : unAccountID - 32-bit account ID
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
void Set( uint32 unAccountID, EUniverse eUniverse, EAccountType eAccountType )
{
m_unAccountID = unAccountID;
m_EUniverse = eUniverse;
m_EAccountType = eAccountType;
m_unAccountInstance = 1;
}
//-----------------------------------------------------------------------------
// Purpose: Sets parameters for steam ID
// Input : unAccountID - 32-bit account ID
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
void InstancedSet( uint32 unAccountID, uint32 unInstance, EUniverse eUniverse, EAccountType eAccountType )
{
m_unAccountID = unAccountID;
m_EUniverse = eUniverse;
m_EAccountType = eAccountType;
m_unAccountInstance = unInstance;
}
//-----------------------------------------------------------------------------
// Purpose: Initializes a steam ID from its 52 bit parts and universe/type
// Input : ulIdentifier - 52 bits of goodness
//-----------------------------------------------------------------------------
void FullSet( uint64 ulIdentifier, EUniverse eUniverse, EAccountType eAccountType )
{
m_unAccountID = ( ulIdentifier & 0xFFFFFFFF ); // account ID is low 32 bits
m_unAccountInstance = ( ( ulIdentifier >> 32 ) & 0xFFFFF ); // account instance is next 20 bits
m_EUniverse = eUniverse;
m_EAccountType = eAccountType;
}
//-----------------------------------------------------------------------------
// Purpose: Initializes a steam ID from its 64-bit representation
// Input : ulSteamID - 64-bit representation of a Steam ID
//-----------------------------------------------------------------------------
void SetFromUint64( uint64 ulSteamID )
{
m_unAccountID = ( ulSteamID & 0xFFFFFFFF ); // account ID is low 32 bits
m_unAccountInstance = ( ( ulSteamID >> 32 ) & 0xFFFFF ); // account instance is next 20 bits
m_EAccountType = ( EAccountType ) ( ( ulSteamID >> 52 ) & 0xF ); // type is next 4 bits
m_EUniverse = ( EUniverse ) ( ( ulSteamID >> 56 ) & 0xFF ); // universe is next 8 bits
}
//-----------------------------------------------------------------------------
// Purpose: Initializes a steam ID from a Steam2 ID structure
// Input: pTSteamGlobalUserID - Steam2 ID to convert
// eUniverse - universe this ID belongs to
//-----------------------------------------------------------------------------
void SetFromSteam2( TSteamGlobalUserID *pTSteamGlobalUserID, EUniverse eUniverse )
{
m_unAccountID = pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits * 2 +
pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits;
m_EUniverse = eUniverse; // set the universe
m_EAccountType = k_EAccountTypeIndividual; // Steam 2 accounts always map to account type of individual
m_unAccountInstance = 1; // individual accounts always have an account instance ID of 1
}
//-----------------------------------------------------------------------------
// Purpose: Converts steam ID to its 64-bit representation
// Output : 64-bit representation of a Steam ID
//-----------------------------------------------------------------------------
uint64 ConvertToUint64( ) const
{
return (uint64) ( ( ( (uint64) m_EUniverse ) << 56 ) + ( ( (uint64) m_EAccountType ) << 52 ) +
( ( (uint64) m_unAccountInstance ) << 32 ) + m_unAccountID );
}
//-----------------------------------------------------------------------------
// Purpose: Fills out a Steam2 ID structure
// Input: pTSteamGlobalUserID - Steam2 ID to write to
//-----------------------------------------------------------------------------
void ConvertToSteam2( TSteamGlobalUserID *pTSteamGlobalUserID ) const
{
// only individual accounts have any meaning in Steam 2, only they can be mapped
// Assert( m_EAccountType == k_EAccountTypeIndividual );
pTSteamGlobalUserID->m_SteamInstanceID = 0;
pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits = m_unAccountID % 2;
pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits = m_unAccountID / 2;
}
//-----------------------------------------------------------------------------
// Purpose: Converts the static parts of a steam ID to a 64-bit representation.
// For multiseat accounts, all instances of that account will have the
// same static account key, so they can be grouped together by the static
// account key.
// Output : 64-bit static account key
//-----------------------------------------------------------------------------
uint64 GetStaticAccountKey( ) const
{
// note we do NOT include the account instance (which is a dynamic property) in the static account key
return (uint64) ( ( ( (uint64) m_EUniverse ) << 56 ) + ((uint64) m_EAccountType << 52 ) + m_unAccountID );
}
//-----------------------------------------------------------------------------
// Purpose: create an anonomous game server login to be filled in by the AM
//-----------------------------------------------------------------------------
void CreateBlankAnonLogon( )
{
m_unAccountID = 0;
m_EAccountType = k_EAccountTypeAnonGameServer;
m_EUniverse = k_EUniversePublic;
m_unAccountInstance = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Is this an anonomous game server login that will be filled in?
//-----------------------------------------------------------------------------
bool BBlankAnonAccount( )
{
return m_unAccountID == 0 &&
m_EAccountType == k_EAccountTypeAnonGameServer &&
m_EUniverse == k_EUniversePublic &&
m_unAccountInstance == 0;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a game server account id?
//-----------------------------------------------------------------------------
bool BGameServerAccount( )
{
return m_EAccountType == k_EAccountTypeGameServer || m_EAccountType == k_EAccountTypeAnonGameServer;
}
// simple accessors
void SetAccountID( uint32 unAccountID ) { m_unAccountID = unAccountID; }
uint32 GetAccountID( ) const { return m_unAccountID; }
uint32 GetUnAccountInstance( ) const { return m_unAccountInstance; }
EAccountType GetEAccountType( ) const { return m_EAccountType; }
EUniverse GetEUniverse( ) const { return m_EUniverse; }
bool IsValid( ) const { return m_EAccountType != k_EAccountTypeInvalid; }
// this set of functions is hidden, will be moved out of class
CSteamID( char *pchSteamID );
void SetFromString( char *pchSteamID );
char * Render( ) const; // renders this steam ID to string
static char * Render( uint64 ulSteamID ); // static method to render a uint64 representation of a steam ID to a string
// DEBUG function
bool BValidExternalSteamID( void );
private:
// 64 bits total
uint32 m_unAccountID : 32; // unique account identifier
unsigned int m_unAccountInstance : 20; // dynamic instance ID (used for multiseat type accounts only)
EAccountType m_EAccountType : 4; // type of account
EUniverse m_EUniverse : 8; // universe this account belongs to
};
#pragma pack( pop )
// ICMCallback
// Anyone who owns a CMInterface object should implement this to receive callbacks.
class ICMCallback
{
public:
ICMCallback( ) { };
virtual ~ICMCallback( ) { };
virtual void OnLogonSuccess( void ) = 0 ;
virtual void OnLogonFailure( EResult eResult ) = 0;
virtual void OnLoggedOff( EResult eResult ) = 0;
// Called during logon to get encrypted user ticket
virtual bool GetEncryptedUserTicket( unsigned int unIPPublic, unsigned int unIPPrivate,
const void * pubEncryptionKey, unsigned int cubEncryptionKey,
void * pubEncryptedTicket, unsigned int cubEncryptedTicketBuf, unsigned int * pcubEncryptedTicketSize ) = 0;
// Called when we receive a VAC challenge
virtual void HandleVACChallenge( int nClientGameID, uint8 *pubChallenge, int cubChallenge ) = 0;
// Called when we receive a VAC kick message
virtual void HandleVACKick( int nClientGameID ) = 0;
// Methods to read/write to owner's persistent storage (e.g. config file)
virtual bool GetValue( const char * pwzName, char * pwzValue, const int cchValue ) = 0;
virtual bool SetValue( const char * pwzName, const char * pwzValue ) = 0;
// called when a GS is getting responses to requests or user status
virtual void GSHandleClientApprove( CSteamID & steamID ) = 0;
virtual void GSHandleClientDeny( CSteamID & steamID, EDenyReason eDenyReason ) = 0;
virtual void GSHandleClientKick( CSteamID & steamID, EDenyReason eDenyReason ) = 0;
#ifdef _SERVER
#ifdef TEST_CODE_ENABLED
virtual void TEST_ReportAuthKey( uint8 * pubAuthKey, uint32 cubAuthKey ) = 0;
virtual void TEST_ReportMsgRecieved( int32 m_EMsg ) = 0;
#endif // TEST_CODE_ENABLED
#endif // _SERVER
};
// CMInterface
// This connects the client to the CM.
class ICMInterface
{
public:
ICMInterface() {};
virtual ~ICMInterface() {};
// Manage ClientGames
virtual int NClientGameIDAdd( int nGameID ) = 0;
virtual void RemoveClientGame( int nClientGameID ) = 0;
virtual void SetClientGameServer( int nClientGameID, uint unIPServer, uint16 usPortServer ) = 0;
// Set CM IP and port -- currently only for debugging!
virtual void SetCMs( const netadr_t *pNetAdrCMs, int nNetAdrCMs ) = 0;
// Log on and off
virtual void LogOff( void ) = 0;
virtual void LogOn( CSteamID & steamID ) = 0;
// Our mainloop
virtual bool BMainLoop( ) = 0;
// Send a VAC response to the CM
virtual bool SendVACResponse( int nClientGameID, uint8 *pubResponse, int cubResponse ) = 0;
// Send an authentication packet to the CM
virtual bool SendAuth( uint8 *pubAuth, int cubAuth ) = 0;
virtual bool BLoggedOn( void ) = 0;
virtual void SetSpewLevel( int nSpewLevel ) = 0;
virtual EUniverse GetEUniverse( ) = 0;
virtual void SetEUniverse( EUniverse eUniverse ) = 0;
// Game Server methods
virtual bool GSSendLogonRequest( CSteamID & steamID ) = 0;
virtual bool GSSendDisconnect( CSteamID & steamID ) = 0;
virtual bool GSSendStatusResponse( CSteamID & steamID, int nSecondsConnected, int nSecondsSinceLast ) = 0;
virtual bool GSSetStatus( int32 uAppIdServed, uint uServerFlags, int cPlayers, int cPlayersMax ) = 0;
#ifdef TEST_CODE_ENABLED
virtual void TEST_SetFakePrivateIP( uint unIPPrivate ) = 0;
virtual void TEST_SendBigMessage( void ) = 0; // send a big (multi-packet) message to the server to test packetization code
virtual bool TEST_BBigMessageResponseReceived( void ) = 0; // returns TRUE if a big test message response has been sent back from the server
virtual void TEST_SetPktLossPct( int nPct ) = 0; // sets a simulated packet loss percentage for testing
virtual void TEST_SetForceTCP( bool bForceTCP ) = 0; // forces client to use TCP connection
virtual void TEST_SetTCPFallback( bool bTCPFallback ) = 0; // causes client to connect over TCP, send a fallback message, and disconnect
virtual int TEST_GetOurConnectionID( ) = 0; // returns our connection ID for this connection
virtual void TEST_HeartBeat( ) = 0; // send a heartbeat to the CM
virtual IVConnCallback * TEST_GetVConnCallback( ) =0; // returns our vconn callback interface
virtual void TEST_FakeDisconnect() = 0;
#endif // TEST_CODE_ENABLED
#ifdef DBGFLAG_VALIDATE
virtual void Validate( CValidator &validator, char *pchName ) = 0; // Validate our internal structures
#endif // DBGFLAG_VALIDATE
};
#ifdef VAC_ENABLED
// IVAC
// This is the wrapper class for all VAC functionaility in the client
class IVAC
{
public:
virtual bool BVACCreateProcess(
PVOID lpVACBlob,
DWORD cbBlobSize,
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
DWORD nGameID
) = 0;
virtual void KillAllVAC( void ) = 0;
virtual void ProcessVAC( ICMInterface *pCMInterface ) = 0;
virtual void RealHandleVACChallenge( ICMInterface *pCMInterface, int nClientGameID, uint8 *pubChallenge, int cubChallenge) = 0;
#ifdef DBGFLAG_VALIDATE
virtual void Validate( CValidator &validator, char *pchName ) = 0; // Validate our internal structures
#endif
};
// this is a bogus number picked to be beyond any real steam2 uAppID
const int k_nGameIDNotepad = 65535;
// this is the real steam2 uAppID for Counter-Strike Source
const int k_nGameIDCSS = 240;
IVAC * IVACGet( void );
void ReleaseIVAC( IVAC *pIVAC );
BYTE *PbLoadVacBlob( int *pcbVacBlob );
void FreeVacBlob( BYTE *pbVacBlob );
#ifdef _DEBUG
void SetUseDllForIVAC( void );
#endif // _DEBUG
#endif // VAC_ENABLED
//lint -restore
#endif // STEAMCLIENTPUBLIC_H