Fixed: Load Steam library if Ryzom compiled with WITH_STEAM, request auth session ticket and send it to login server
This commit is contained in:
parent
24451d67ab
commit
bfb2c7d222
7 changed files with 508 additions and 7 deletions
60
code/CMakeModules/FindSteam.cmake
Normal file
60
code/CMakeModules/FindSteam.cmake
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# - Locate Steam API
|
||||||
|
# This module defines
|
||||||
|
# STEAM_LIBRARY, the library to link against
|
||||||
|
# VORBIS_FOUND, if false, do not try to link to VORBIS
|
||||||
|
# VORBIS_INCLUDE_DIR, where to find headers.
|
||||||
|
|
||||||
|
IF(STEAM_LIBRARY AND STEAM_INCLUDE_DIR)
|
||||||
|
# in cache already
|
||||||
|
SET(Steam_FIND_QUIETLY TRUE)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
FIND_PATH(STEAM_INCLUDE_DIR
|
||||||
|
steam_api.h
|
||||||
|
PATH_SUFFIXES steam
|
||||||
|
PATHS
|
||||||
|
$ENV{STEAM_DIR}/public
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
IF(TARGET_X64)
|
||||||
|
SET(STEAM_LIBNAME steam_api64)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/win64)
|
||||||
|
ELSE()
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin)
|
||||||
|
ENDIF()
|
||||||
|
ELSEIF(APPLE)
|
||||||
|
# universal binary
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/osx32)
|
||||||
|
ELSE()
|
||||||
|
IF(TARGET_X64)
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/linux64)
|
||||||
|
ELSE()
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/linux32)
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
FIND_LIBRARY(STEAM_LIBRARY
|
||||||
|
NAMES ${STEAM_LIBNAME}
|
||||||
|
PATHS
|
||||||
|
$ENV{STEAM_DIR}/${STEAM_PATHNAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Don't need to check STEAM_LIBRARY because we're dynamically loading Steam DLL
|
||||||
|
IF(STEAM_INCLUDE_DIR)
|
||||||
|
SET(STEAM_FOUND ON)
|
||||||
|
SET(STEAM_LIBRARIES ${STEAM_LIBRARY})
|
||||||
|
SET(STEAM_INCLUDE_DIRS ${STEAM_INCLUDE_DIR})
|
||||||
|
IF(NOT Steam_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS "Found Steam: ${STEAM_INCLUDE_DIR}")
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
IF(NOT Steam_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS "Warning: Unable to find Steam!")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
|
@ -6,7 +6,10 @@ ADD_SUBDIRECTORY(seven_zip)
|
||||||
|
|
||||||
IF(WITH_RYZOM_CLIENT)
|
IF(WITH_RYZOM_CLIENT)
|
||||||
# Patch should never be enabled on Steam
|
# Patch should never be enabled on Steam
|
||||||
IF(WITH_RYZOM_PATCH AND NOT WITH_RYZOM_STEAM)
|
IF(WITH_RYZOM_STEAM)
|
||||||
|
ADD_DEFINITIONS(-DRZ_USE_STEAM)
|
||||||
|
FIND_PACKAGE(Steam)
|
||||||
|
ELSEIF(WITH_RYZOM_PATCH)
|
||||||
ADD_DEFINITIONS(-DRZ_USE_PATCH)
|
ADD_DEFINITIONS(-DRZ_USE_PATCH)
|
||||||
|
|
||||||
IF(WITH_RYZOM_CUSTOM_PATCH_SERVER)
|
IF(WITH_RYZOM_CUSTOM_PATCH_SERVER)
|
||||||
|
@ -127,6 +130,10 @@ IF(WITH_RYZOM_CLIENT)
|
||||||
${ZLIB_INCLUDE_DIR}
|
${ZLIB_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF(STEAM_FOUND)
|
||||||
|
INCLUDE_DIRECTORIES(${STEAM_INCLUDE_DIRS})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(ryzom_client
|
TARGET_LINK_LIBRARIES(ryzom_client
|
||||||
nelmisc
|
nelmisc
|
||||||
nelnet
|
nelnet
|
||||||
|
|
|
@ -62,6 +62,10 @@
|
||||||
#include "client_cfg.h"
|
#include "client_cfg.h"
|
||||||
#include "far_tp.h"
|
#include "far_tp.h"
|
||||||
|
|
||||||
|
#ifdef RZ_USE_STEAM
|
||||||
|
#include "steam_client.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// USING //
|
// USING //
|
||||||
///////////
|
///////////
|
||||||
|
@ -319,6 +323,13 @@ int main(int argc, char **argv)
|
||||||
prelogInit();
|
prelogInit();
|
||||||
RYZOM_CATCH("Pre-Login Init")
|
RYZOM_CATCH("Pre-Login Init")
|
||||||
|
|
||||||
|
#ifdef RZ_USE_STEAM
|
||||||
|
CSteamClient steamClient;
|
||||||
|
|
||||||
|
if (steamClient.init())
|
||||||
|
LoginCustomParameters = "&steam_auth_session_ticket=" + steamClient.getAuthSessionTicket();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Log the client and choose from shard
|
// Log the client and choose from shard
|
||||||
RYZOM_TRY("Login")
|
RYZOM_TRY("Login")
|
||||||
if (!ClientCfg.Local && (ClientCfg.TestBrowser || ClientCfg.FSHost.empty()))
|
if (!ClientCfg.Local && (ClientCfg.TestBrowser || ClientCfg.FSHost.empty()))
|
||||||
|
|
|
@ -77,7 +77,7 @@ extern bool SetMousePosFirstTime;
|
||||||
|
|
||||||
vector<CShard> Shards;
|
vector<CShard> Shards;
|
||||||
|
|
||||||
string LoginLogin, LoginPassword, ClientApp, Salt;
|
string LoginLogin, LoginPassword, ClientApp, Salt, LoginCustomParameters;
|
||||||
uint32 LoginShardId = 0xFFFFFFFF;
|
uint32 LoginShardId = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1169,7 +1169,7 @@ void onlogin(bool vanishScreen = true)
|
||||||
// Check the login/pass
|
// Check the login/pass
|
||||||
|
|
||||||
// main menu page for r2mode
|
// main menu page for r2mode
|
||||||
string res = checkLogin(LoginLogin, LoginPassword, ClientApp);
|
string res = checkLogin(LoginLogin, LoginPassword, ClientApp, LoginCustomParameters);
|
||||||
if (res.empty())
|
if (res.empty())
|
||||||
{
|
{
|
||||||
// if not in auto login, push login ok event
|
// if not in auto login, push login ok event
|
||||||
|
@ -2738,7 +2738,7 @@ REGISTER_ACTION_HANDLER (CAHOnBackToLogin, "on_back_to_login");
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
string checkLogin(const string &login, const string &password, const string &clientApp)
|
string checkLogin(const string &login, const string &password, const string &clientApp, const std::string &customParameters)
|
||||||
{
|
{
|
||||||
CPatchManager *pPM = CPatchManager::getInstance();
|
CPatchManager *pPM = CPatchManager::getInstance();
|
||||||
Shards.clear();
|
Shards.clear();
|
||||||
|
@ -2795,7 +2795,7 @@ string checkLogin(const string &login, const string &password, const string &cli
|
||||||
{
|
{
|
||||||
// R2 login sequence
|
// R2 login sequence
|
||||||
std::string cryptedPassword = CCrypt::crypt(password, Salt);
|
std::string cryptedPassword = CCrypt::crypt(password, Salt);
|
||||||
if(!HttpClient.sendGet(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?cmd=login&login="+login+"&password="+cryptedPassword+"&clientApplication="+clientApp+"&cp=1"+"&lg="+ClientCfg.LanguageCode))
|
if(!HttpClient.sendGet(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?cmd=login&login="+login+"&password="+cryptedPassword+"&clientApplication="+clientApp+"&cp=1"+"&lg="+ClientCfg.LanguageCode+customParameters))
|
||||||
return "Can't send (error code 2)";
|
return "Can't send (error code 2)";
|
||||||
|
|
||||||
// the response should contains the result code and the cookie value
|
// the response should contains the result code and the cookie value
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct CShard
|
||||||
std::string EmergencyPatchURL;
|
std::string EmergencyPatchURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::string LoginLogin, LoginPassword;
|
extern std::string LoginLogin, LoginPassword, LoginCustomParameters;
|
||||||
extern uint32 LoginShardId;
|
extern uint32 LoginShardId;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ extern uint32 AvailablePatchs;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string checkLogin(const std::string &login, const std::string &password, const std::string &clientApp);
|
std::string checkLogin(const std::string &login, const std::string &password, const std::string &clientApp, const std::string &customParameters = "");
|
||||||
std::string selectShard(uint32 shardId, std::string &cookie, std::string &addr);
|
std::string selectShard(uint32 shardId, std::string &cookie, std::string &addr);
|
||||||
std::string getBGDownloaderCommandLine();
|
std::string getBGDownloaderCommandLine();
|
||||||
|
|
||||||
|
|
358
code/ryzom/client/src/steam_client.cpp
Normal file
358
code/ryzom/client/src/steam_client.cpp
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "stdpch.h"
|
||||||
|
|
||||||
|
#ifdef RZ_USE_STEAM
|
||||||
|
|
||||||
|
#include "steam_client.h"
|
||||||
|
|
||||||
|
#include <steam_api.h>
|
||||||
|
|
||||||
|
// prototypes definitions for Steam API functions we'll call
|
||||||
|
typedef bool (__cdecl *SteamAPI_InitFuncPtr)();
|
||||||
|
typedef void (__cdecl *SteamAPI_RegisterCallbackFuncPtr)(class CCallbackBase *pCallback, int iCallback);
|
||||||
|
typedef void (__cdecl *SteamAPI_RunCallbacksFuncPtr)();
|
||||||
|
typedef void (__cdecl *SteamAPI_ShutdownFuncPtr)();
|
||||||
|
typedef void (__cdecl *SteamAPI_UnregisterCallbackFuncPtr)(class CCallbackBase *pCallback);
|
||||||
|
typedef ISteamUtils* (__cdecl *SteamUtilsFuncPtr)();
|
||||||
|
typedef ISteamUser* (__cdecl *SteamUserFuncPtr)();
|
||||||
|
typedef ISteamFriends* (__cdecl *SteamFriendsFuncPtr)();
|
||||||
|
|
||||||
|
// macros to simplify dynamic functions loading
|
||||||
|
#define NL_DECLARE_SYMBOL(symbol) symbol##FuncPtr nl##symbol = NULL
|
||||||
|
#define NL_LOAD_SYMBOL(symbol) nl##symbol = (symbol##FuncPtr)NLMISC::nlGetSymbolAddress(_Handle, #symbol)
|
||||||
|
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_Init);
|
||||||
|
NL_DECLARE_SYMBOL(SteamFriends);
|
||||||
|
NL_DECLARE_SYMBOL(SteamUser);
|
||||||
|
NL_DECLARE_SYMBOL(SteamUtils);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_RegisterCallback);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_UnregisterCallback);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_RunCallbacks);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_Shutdown);
|
||||||
|
|
||||||
|
// taken from steam_api.h, we needed to change it to use our dynamically loaded functions
|
||||||
|
|
||||||
|
// Declares a callback member function plus a helper member variable which
|
||||||
|
// registers the callback on object creation and unregisters on destruction.
|
||||||
|
// The optional fourth 'var' param exists only for backwards-compatibility
|
||||||
|
// and can be ignored.
|
||||||
|
#define NL_STEAM_CALLBACK( thisclass, func, .../*callback_type, [deprecated] var*/ ) \
|
||||||
|
_NL_STEAM_CALLBACK_SELECT( ( __VA_ARGS__, 4, 3 ), ( /**/, thisclass, func, __VA_ARGS__ ) )
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// The following macros are implementation details, not intended for public use
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#define _NL_STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param )
|
||||||
|
#define _NL_STEAM_CALLBACK_HELPER( _1, _2, SELECTED, ... ) _NL_STEAM_CALLBACK_##SELECTED
|
||||||
|
#define _NL_STEAM_CALLBACK_SELECT( X, Y ) _NL_STEAM_CALLBACK_HELPER X Y
|
||||||
|
#define _NL_STEAM_CALLBACK_3( extra_code, thisclass, func, param ) \
|
||||||
|
struct CCallbackInternal_ ## func : private CSteamCallbackImpl< sizeof( param ) > { \
|
||||||
|
CCallbackInternal_ ## func () { extra_code nlSteamAPI_RegisterCallback( this, param::k_iCallback ); } \
|
||||||
|
CCallbackInternal_ ## func ( const CCallbackInternal_ ## func & ) { extra_code nlSteamAPI_RegisterCallback( this, param::k_iCallback ); } \
|
||||||
|
CCallbackInternal_ ## func & operator=( const CCallbackInternal_ ## func & ) { return *this; } \
|
||||||
|
private: virtual void Run( void *pvParam ) { _NL_STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param ) \
|
||||||
|
thisclass *pOuter = reinterpret_cast<thisclass*>( reinterpret_cast<char*>(this) - offsetof( thisclass, m_steamcallback_ ## func ) ); \
|
||||||
|
pOuter->func( reinterpret_cast<param*>( pvParam ) ); \
|
||||||
|
} \
|
||||||
|
} m_steamcallback_ ## func ; void func( param *pParam )
|
||||||
|
#define _NL_STEAM_CALLBACK_4( _, thisclass, func, param, var ) \
|
||||||
|
CSteamCallback< thisclass, param > var; void func( param *pParam )
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: templated base for callbacks - internal implementation detail
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template< int sizeof_P >
|
||||||
|
class CSteamCallbackImpl : protected CCallbackBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~CSteamCallbackImpl() { if ( m_nCallbackFlags & k_ECallbackFlagsRegistered ) nlSteamAPI_UnregisterCallback( this ); }
|
||||||
|
void SetGameserverFlag() { m_nCallbackFlags |= k_ECallbackFlagsGameServer; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Run( void *pvParam ) = 0;
|
||||||
|
virtual void Run( void *pvParam, bool /*bIOFailure*/, SteamAPICall_t /*hSteamAPICall*/ ) { Run( pvParam ); }
|
||||||
|
virtual int GetCallbackSizeBytes() { return sizeof_P; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: maps a steam callback to a class member function
|
||||||
|
// template params: T = local class, P = parameter struct,
|
||||||
|
// bGameserver = listen for gameserver callbacks instead of client callbacks
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template< class T, class P, bool bGameserver = false >
|
||||||
|
class CSteamCallback : public CSteamCallbackImpl< sizeof( P ) >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef void (T::*func_t)(P*);
|
||||||
|
|
||||||
|
// NOTE: If you can't provide the correct parameters at construction time, you should
|
||||||
|
// use the CCallbackManual callback object (STEAM_CALLBACK_MANUAL macro) instead.
|
||||||
|
CSteamCallback( T *pObj, func_t func ) : m_pObj( NULL ), m_Func( NULL )
|
||||||
|
{
|
||||||
|
if ( bGameserver )
|
||||||
|
{
|
||||||
|
this->SetGameserverFlag();
|
||||||
|
}
|
||||||
|
Register( pObj, func );
|
||||||
|
}
|
||||||
|
|
||||||
|
// manual registration of the callback
|
||||||
|
void Register( T *pObj, func_t func )
|
||||||
|
{
|
||||||
|
if ( !pObj || !func )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( this->m_nCallbackFlags & CCallbackBase::k_ECallbackFlagsRegistered )
|
||||||
|
Unregister();
|
||||||
|
|
||||||
|
m_pObj = pObj;
|
||||||
|
m_Func = func;
|
||||||
|
// SteamAPI_RegisterCallback sets k_ECallbackFlagsRegistered
|
||||||
|
nlSteamAPI_RegisterCallback( this, P::k_iCallback );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unregister()
|
||||||
|
{
|
||||||
|
// SteamAPI_UnregisterCallback removes k_ECallbackFlagsRegistered
|
||||||
|
nlSteamAPI_UnregisterCallback( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Run( void *pvParam )
|
||||||
|
{
|
||||||
|
(m_pObj->*m_Func)( (P *)pvParam );
|
||||||
|
}
|
||||||
|
|
||||||
|
T *m_pObj;
|
||||||
|
func_t m_Func;
|
||||||
|
};
|
||||||
|
|
||||||
|
// listener called by Steam when AuthSessionTicket is available
|
||||||
|
class CAuthSessionTicketListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAuthSessionTicketListener():_AuthSessionTicketResponse(this, &CAuthSessionTicketListener::OnAuthSessionTicketResponse)
|
||||||
|
{
|
||||||
|
_AuthSessionTicketHandle = 0;
|
||||||
|
_AuthSessionTicketSize = 0;
|
||||||
|
|
||||||
|
_AuthSessionTicketCallbackCalled = false;
|
||||||
|
_AuthSessionTicketCallbackError = false;;
|
||||||
|
_AuthSessionTicketCallbackTimeout = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until a ticket is available or return if no ticket received after specified ms
|
||||||
|
bool waitTicket(uint32 ms)
|
||||||
|
{
|
||||||
|
// call Steam method
|
||||||
|
_AuthSessionTicketHandle = nlSteamUser()->GetAuthSessionTicket(_AuthSessionTicketData, sizeof(_AuthSessionTicketData), &_AuthSessionTicketSize);
|
||||||
|
|
||||||
|
nldebug("GetAuthSessionTicket returned %u bytes, handle %u", _AuthSessionTicketSize, _AuthSessionTicketHandle);
|
||||||
|
|
||||||
|
nlinfo("Waiting for Steam GetAuthSessionTicket callback...");
|
||||||
|
|
||||||
|
// define expiration time
|
||||||
|
NLMISC::TTime expirationTime = NLMISC::CTime::getLocalTime() + ms;
|
||||||
|
|
||||||
|
// wait until callback method is called or expiration
|
||||||
|
while(!_AuthSessionTicketCallbackCalled && !_AuthSessionTicketCallbackTimeout)
|
||||||
|
{
|
||||||
|
// call registered callbacks
|
||||||
|
nlSteamAPI_RunCallbacks();
|
||||||
|
|
||||||
|
// check if expired
|
||||||
|
if (NLMISC::CTime::getLocalTime() > expirationTime)
|
||||||
|
_AuthSessionTicketCallbackTimeout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// expired
|
||||||
|
if (_AuthSessionTicketCallbackTimeout)
|
||||||
|
{
|
||||||
|
nlwarning("GetAuthSessionTicket callback never called");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlinfo("GetAuthSessionTicket called");
|
||||||
|
|
||||||
|
// got an error
|
||||||
|
if (_AuthSessionTicketCallbackError)
|
||||||
|
{
|
||||||
|
nlwarning("GetAuthSessionTicket callback returned error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return ticket if available in hexadecimal
|
||||||
|
std::string getTicket() const
|
||||||
|
{
|
||||||
|
// if expired or error, ticket is not available
|
||||||
|
if (!_AuthSessionTicketCallbackCalled || _AuthSessionTicketCallbackError || _AuthSessionTicketCallbackTimeout) return "";
|
||||||
|
|
||||||
|
std::string authSessionTicket;
|
||||||
|
|
||||||
|
// optimize string by allocating the final string size
|
||||||
|
authSessionTicket.reserve(_AuthSessionTicketSize*2);
|
||||||
|
|
||||||
|
// convert buffer to hexadecimal string
|
||||||
|
for (uint32 i = 0; i < _AuthSessionTicketSize; ++i)
|
||||||
|
{
|
||||||
|
authSessionTicket += NLMISC::toString("%02x", _AuthSessionTicketData[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return authSessionTicket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ticket handle
|
||||||
|
HAuthTicket _AuthSessionTicketHandle;
|
||||||
|
|
||||||
|
// buffer of ticket data
|
||||||
|
uint8 _AuthSessionTicketData[1024];
|
||||||
|
|
||||||
|
// size of buffer
|
||||||
|
uint32 _AuthSessionTicketSize;
|
||||||
|
|
||||||
|
// different states of callback
|
||||||
|
bool _AuthSessionTicketCallbackCalled;
|
||||||
|
bool _AuthSessionTicketCallbackError;
|
||||||
|
bool _AuthSessionTicketCallbackTimeout;
|
||||||
|
|
||||||
|
// callback declaration
|
||||||
|
NL_STEAM_CALLBACK(CAuthSessionTicketListener, OnAuthSessionTicketResponse, GetAuthSessionTicketResponse_t, _AuthSessionTicketResponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
// method called by Steam
|
||||||
|
void CAuthSessionTicketListener::OnAuthSessionTicketResponse(GetAuthSessionTicketResponse_t *inCallback)
|
||||||
|
{
|
||||||
|
_AuthSessionTicketCallbackCalled = true;
|
||||||
|
|
||||||
|
if (inCallback->m_eResult != k_EResultOK)
|
||||||
|
{
|
||||||
|
_AuthSessionTicketCallbackError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSteamClient::CSteamClient():_Handle(NULL), _Initialized(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSteamClient::~CSteamClient()
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSteamClient::init()
|
||||||
|
{
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
#if defined(NL_OS_WIN64)
|
||||||
|
filename = "steam_api64.dll";
|
||||||
|
#elif defined(NL_OS_WINDOWS)
|
||||||
|
filename = "steam_api.dll";
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
filename = "libsteam_api.dylib";
|
||||||
|
#else
|
||||||
|
filename = "libsteam_api.so";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// try to load library
|
||||||
|
_Handle = NLMISC::nlLoadLibrary(filename);
|
||||||
|
|
||||||
|
if (!_Handle)
|
||||||
|
{
|
||||||
|
nlwarning("Unable to load Steam client");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_Init);
|
||||||
|
|
||||||
|
// check if function was found
|
||||||
|
if (!nlSteamAPI_Init)
|
||||||
|
{
|
||||||
|
nlwarning("Unable to get a pointer on SteamAPI_Init");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize Steam API
|
||||||
|
if (!nlSteamAPI_Init())
|
||||||
|
{
|
||||||
|
nlwarning("Unable to initialize Steam client");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Initialized = true;
|
||||||
|
|
||||||
|
// load more functions
|
||||||
|
NL_LOAD_SYMBOL(SteamFriends);
|
||||||
|
NL_LOAD_SYMBOL(SteamUser);
|
||||||
|
NL_LOAD_SYMBOL(SteamUtils);
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_Shutdown);
|
||||||
|
|
||||||
|
bool loggedOn = nlSteamUser()->BLoggedOn();
|
||||||
|
|
||||||
|
nlinfo("Steam AppID: %u", nlSteamUtils()->GetAppID());
|
||||||
|
nlinfo("Steam login: %s", nlSteamFriends()->GetPersonaName());
|
||||||
|
nlinfo("Steam user logged: %s", loggedOn ? "yes":"no");
|
||||||
|
|
||||||
|
// don't need to continue, if not connected
|
||||||
|
if (!loggedOn) return false;
|
||||||
|
|
||||||
|
// load symbols used by AuthSessionTicket
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_RegisterCallback);
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_UnregisterCallback);
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_RunCallbacks);
|
||||||
|
|
||||||
|
CAuthSessionTicketListener listener;
|
||||||
|
|
||||||
|
// wait 5 seconds to get ticket
|
||||||
|
if (!listener.waitTicket(5000)) return false;
|
||||||
|
|
||||||
|
// save ticket
|
||||||
|
_AuthSessionTicket = listener.getTicket();
|
||||||
|
|
||||||
|
nldebug("Auth ticket: %s", _AuthSessionTicket.c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSteamClient::release()
|
||||||
|
{
|
||||||
|
if (!_Handle) return false;
|
||||||
|
|
||||||
|
if (_Initialized)
|
||||||
|
{
|
||||||
|
// only shutdown Steam if initialized
|
||||||
|
nlSteamAPI_Shutdown();
|
||||||
|
|
||||||
|
_Initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free Steam library from memory
|
||||||
|
bool res = NLMISC::nlFreeLibrary(_Handle);
|
||||||
|
|
||||||
|
_Handle = NULL;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
65
code/ryzom/client/src/steam_client.h
Normal file
65
code/ryzom/client/src/steam_client.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CL_STEAM_CLIENT_H
|
||||||
|
#define CL_STEAM_CLIENT_H
|
||||||
|
|
||||||
|
#include "nel/misc/types_nl.h"
|
||||||
|
#include "nel/misc/dynloadlib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steam API helper to be able to call Steam functions/methods without linking to any library.
|
||||||
|
* The library is dynamically loaded and is optional.
|
||||||
|
*
|
||||||
|
* \author Cedric 'Kervala' OCHS
|
||||||
|
* \date 2016
|
||||||
|
*/
|
||||||
|
class CSteamClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CSteamClient();
|
||||||
|
~CSteamClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically load Steam client library and functions pointers.
|
||||||
|
* Also retrieve authentication session ticket if available.
|
||||||
|
* If no authentication session ticket retrieved, returns false.
|
||||||
|
*/
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown Steam client and unload library.
|
||||||
|
*/
|
||||||
|
bool release();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the authentication session ticket if available.
|
||||||
|
*/
|
||||||
|
std::string getAuthSessionTicket() const { return _AuthSessionTicket; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// handle on Steam DLL
|
||||||
|
NLMISC::NL_LIB_HANDLE _Handle;
|
||||||
|
|
||||||
|
// true if succeeded to initialize (must call shutdown)
|
||||||
|
bool _Initialized;
|
||||||
|
|
||||||
|
// the retrieved authentication session ticket
|
||||||
|
std::string _AuthSessionTicket;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue