476 lines
18 KiB
C++
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
|