diff --git a/r5dev/common/global.cpp b/r5dev/common/global.cpp index d12ae85e..fe73e35e 100644 --- a/r5dev/common/global.cpp +++ b/r5dev/common/global.cpp @@ -65,6 +65,12 @@ ConVar* language_cvar = nullptr; ConVar* voice_noxplat = nullptr; +ConVar* platform_user_id = nullptr; + +#ifndef DEDICATED +ConVar* name_cvar = nullptr; +#endif // !DEDICATED + //----------------------------------------------------------------------------- // SERVER | #ifndef CLIENT_DLL @@ -156,7 +162,9 @@ void ConVar_InitShipped(void) language_cvar = g_pCVar->FindVar("language"); voice_noxplat = g_pCVar->FindVar("voice_noxplat"); + platform_user_id = g_pCVar->FindVar("platform_user_id"); #ifndef DEDICATED + name_cvar = g_pCVar->FindVar("name"); cl_updaterate_mp = g_pCVar->FindVar("cl_updaterate_mp"); cl_threaded_bone_setup = g_pCVar->FindVar("cl_threaded_bone_setup"); #endif // !DEDICATED diff --git a/r5dev/common/global.h b/r5dev/common/global.h index 139ad327..5df2c062 100644 --- a/r5dev/common/global.h +++ b/r5dev/common/global.h @@ -52,6 +52,12 @@ extern ConVar* language_cvar; extern ConVar* voice_noxplat; +extern ConVar* platform_user_id; + +#ifndef DEDICATED +extern ConVar* name_cvar; +#endif // !DEDICATED + //------------------------------------------------------------------------- // SERVER | #ifndef CLIENT_DLL diff --git a/r5dev/ebisusdk/EbisuSDK.cpp b/r5dev/ebisusdk/EbisuSDK.cpp index a082356f..1487a250 100644 --- a/r5dev/ebisusdk/EbisuSDK.cpp +++ b/r5dev/ebisusdk/EbisuSDK.cpp @@ -4,18 +4,47 @@ #include "engine/server/sv_main.h" //----------------------------------------------------------------------------- -// Purpose: sets the EbisuSDK globals for dedicated to satisfy command callbacks +// Purpose: initialize the EbisuSDK //----------------------------------------------------------------------------- void HEbisuSDK_Init() { - if (IsDedicated()) + const bool isDedicated = IsDedicated(); + const bool noOrigin = IsOriginDisabled(); + + // Fill with default data if this is a dedicated server, or if the game was + // launched with the platform system disabled. Engine code requires these + // to be set for the game to function, else stuff like the "map" command + // won't run as 'IsOriginInitialized()' returns false (which got inlined in + // every place this was called in the game's executable). + if (isDedicated || noOrigin) { - *g_EbisuSDKInit = true; // <- 1st EbisuSDK - *g_EbisuProfileInit = true; // <- 2nd EbisuSDK - *g_NucleusID = 9990000; // <- 3rd EbisuSDK + *g_EbisuSDKInit = true; + *g_EbisuProfileInit = true; + *g_NucleusID = FAKE_BASE_NUCLEUD_ID; + + Q_snprintf(g_OriginAuthCode, 256, "%s", "INVALID_OAUTH_CODE"); + Q_snprintf(g_NucleusToken, 1024, "%s", "INVALID_NUCLEUS_TOKEN"); + + if (!isDedicated) + { + platform_user_id->SetValue(FAKE_BASE_NUCLEUD_ID); + } } } +//----------------------------------------------------------------------------- +// Purpose: runs the EbisuSDK state machine +//----------------------------------------------------------------------------- +void HEbisuSDK_RunFrame() +{ + if (IsOriginDisabled()) + { + return; + } + + EbisuSDK_RunFrame(); +} + //----------------------------------------------------------------------------- // Purpose: returns the currently set language //----------------------------------------------------------------------------- @@ -52,6 +81,16 @@ const char* HEbisuSDK_GetLanguage() return languageName; } +//----------------------------------------------------------------------------- +// Purpose: checks if the EbisuSDK is disabled +// Output : true on success, false on failure +//----------------------------------------------------------------------------- +bool IsOriginDisabled() +{ + const static bool isDisabled = CommandLine()->CheckParm("-noorigin"); + return isDisabled; +} + //----------------------------------------------------------------------------- // Purpose: checks if the EbisuSDK is initialized // Output : true on success, false on failure @@ -97,5 +136,6 @@ bool IsValidPersonaName(const char* pszName, int nMinLen, int nMaxLen) void VEbisuSDK::Detour(const bool bAttach) const { + DetourSetup(&EbisuSDK_RunFrame, &HEbisuSDK_RunFrame, bAttach); DetourSetup(&EbisuSDK_GetLanguage, &HEbisuSDK_GetLanguage, bAttach); } diff --git a/r5dev/ebisusdk/EbisuSDK.h b/r5dev/ebisusdk/EbisuSDK.h index caf1f16c..79dbaaa7 100644 --- a/r5dev/ebisusdk/EbisuSDK.h +++ b/r5dev/ebisusdk/EbisuSDK.h @@ -1,13 +1,17 @@ #pragma once +#define MAX_PERSONA_NAME_LEN 64 // sizeof( g_PersonaName ) +#define FAKE_BASE_NUCLEUD_ID 9990000 + inline void(*EbisuSDK_Tier0_Init)(void); inline void(*EbisuSDK_CVar_Init)(void); -inline void(*EbisuSDK_SetState)(void); +inline void(*EbisuSDK_RunFrame)(void); inline const char*(*EbisuSDK_GetLanguage)(void); inline uint64_t* g_NucleusID = nullptr; inline char* g_NucleusToken = nullptr; /*SIZE = 1024*/ inline char* g_OriginAuthCode = nullptr; /*SIZE = 256*/ +inline char* g_PersonaName = nullptr; /*SIZE = 64*/ inline int* g_OriginErrorLevel = nullptr; inline bool* g_EbisuSDKInit = nullptr; inline bool* g_EbisuProfileInit = nullptr; @@ -16,7 +20,9 @@ inline bool* g_EbisuProfileInit = nullptr; void HEbisuSDK_Init(); const char* HEbisuSDK_GetLanguage(); +bool IsOriginDisabled(); bool IsOriginInitialized(); + bool IsValidPersonaName(const char* pszName, int nMinLen, int nMaxLen); /////////////////////////////////////////////////////////////////////////////// @@ -26,11 +32,12 @@ class VEbisuSDK : public IDetour { LogFunAdr("EbisuSDK_Tier0_Init", EbisuSDK_Tier0_Init); LogFunAdr("EbisuSDK_CVar_Init", EbisuSDK_CVar_Init); - LogFunAdr("EbisuSDK_SetState", EbisuSDK_SetState); - LogFunAdr("EbisuSDK_SetState", EbisuSDK_GetLanguage); + LogFunAdr("EbisuSDK_RunFrame", EbisuSDK_RunFrame); + LogFunAdr("EbisuSDK_GetLanguage", EbisuSDK_GetLanguage); LogVarAdr("g_NucleusID", g_NucleusID); LogVarAdr("g_NucleusToken", g_NucleusToken); LogVarAdr("g_OriginAuthCode", g_OriginAuthCode); + LogVarAdr("g_PersonaName", g_PersonaName); LogVarAdr("g_OriginErrorLevel", g_OriginErrorLevel); LogVarAdr("g_EbisuProfileInit", g_EbisuProfileInit); LogVarAdr("g_EbisuSDKInit", g_EbisuSDKInit); @@ -39,15 +46,16 @@ class VEbisuSDK : public IDetour { g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 0F 85 ?? 02 ?? ?? 48 89 5C 24 20").GetPtr(EbisuSDK_Tier0_Init); g_GameDll.FindPatternSIMD("40 57 48 83 EC 40 83 3D").GetPtr(EbisuSDK_CVar_Init); - g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B").GetPtr(EbisuSDK_SetState); + g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B").GetPtr(EbisuSDK_RunFrame); g_GameDll.FindPatternSIMD("48 8B C4 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ??").GetPtr(EbisuSDK_GetLanguage); } virtual void GetVar(void) const { g_NucleusID = CMemory(EbisuSDK_CVar_Init).Offset(0x20).FindPatternSelf("4C 89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - g_NucleusToken = CMemory(EbisuSDK_SetState).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); - g_OriginAuthCode = CMemory(EbisuSDK_SetState).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - g_OriginErrorLevel = CMemory(EbisuSDK_SetState).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast(); + g_NucleusToken = CMemory(EbisuSDK_RunFrame).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); + g_OriginAuthCode = CMemory(EbisuSDK_RunFrame).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_PersonaName = CMemory(EbisuSDK_CVar_Init).Offset(0x120).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_OriginErrorLevel = CMemory(EbisuSDK_RunFrame).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast(); g_EbisuProfileInit = CMemory(EbisuSDK_CVar_Init).Offset(0x12A).FindPatternSelf("C6 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); g_EbisuSDKInit = CMemory(EbisuSDK_Tier0_Init).Offset(0x0).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); } diff --git a/r5dev/engine/client/clientstate.cpp b/r5dev/engine/client/clientstate.cpp index 2a2a57c0..f8064e02 100644 --- a/r5dev/engine/client/clientstate.cpp +++ b/r5dev/engine/client/clientstate.cpp @@ -25,6 +25,36 @@ #include #include +//------------------------------------------------------------------------------ +// Purpose: console command callbacks +//------------------------------------------------------------------------------ +static void SetName_f(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + if (!IsOriginDisabled()) + return; + + const char* pszName = args.Arg(1); + + if (!pszName[0]) + pszName = "unnamed"; + + const size_t nLen = strlen(pszName); + + if (nLen > MAX_PERSONA_NAME_LEN) + return; + + // Update nucleus name. + memset(g_PersonaName, '\0', MAX_PERSONA_NAME_LEN); + strncpy(g_PersonaName, pszName, nLen); +} + +//------------------------------------------------------------------------------ +// Purpose: console commands +//------------------------------------------------------------------------------ +static ConCommand cl_setname("cl_setname", SetName_f, "Sets the client's persona name", FCVAR_RELEASE); //------------------------------------------------------------------------------ // Purpose: returns true if client simulation is paused