Implement ICvar interface class

Reversed ICvar interface class. Has been tested and verified on assembly level.
This commit is contained in:
Kawe Mazidjatari 2023-02-05 11:01:27 +01:00
parent 4116edfe4c
commit 87ff71675b
6 changed files with 177 additions and 136 deletions

View File

@ -76,4 +76,33 @@ public:
virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0; virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0;
}; };
//-----------------------------------------------------------------------------
// Helper empty implementation of an IAppSystem
//-----------------------------------------------------------------------------
template< class IInterface >
class CBaseAppSystem : public IInterface
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect(CreateInterfaceFn factory) = 0;
virtual void Disconnect() = 0;
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void* QueryInterface(const char* pInterfaceName) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
// Returns all dependent libraries
//virtual const AppSystemInfo_t* GetDependencies() { return NULL; }
// Returns the tier
virtual AppSystemTier_t GetTier() = 0;
// Reconnect to a particular interface
virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0;
};
#endif // IAPPSYSTEM_H #endif // IAPPSYSTEM_H

View File

@ -1,10 +1,16 @@
#ifndef ICVAR_H #ifndef ICVAR_H
#define ICVAR_H #define ICVAR_H
#include "tier0/annotations.h"
#include "appframework/IAppSystem.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Forward declarations // Forward declarations
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class ConCommandBase; class ConCommandBase;
class ConCommand;
class ConVar;
class IAppSystem;
class Color;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// ConVars/ComCommands are marked as having a particular DLL identifier // ConVars/ComCommands are marked as having a particular DLL identifier
@ -16,13 +22,105 @@ typedef int CVarDLLIdentifier_t;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
typedef int CVarDLLIdentifier_t; typedef int CVarDLLIdentifier_t;
abstract_class ICVarIteratorInternal //-----------------------------------------------------------------------------
// Used to display console messages
//-----------------------------------------------------------------------------
abstract_class IConsoleDisplayFunc
{ {
public: public:
virtual void SetFirst(void) = 0; virtual void ColorPrint(const Color & clr, const char* pMessage) = 0;
virtual void Next(void) = 0; virtual void Print(const char* pMessage) = 0;
virtual bool IsValid(void) = 0; virtual void DPrint(const char* pMessage) = 0;
virtual ConCommandBase* Get(void) = 0;
virtual void GetConsoleText(char* pchText, size_t bufSize) const = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Applications can implement this to modify behavior in ICvar
//-----------------------------------------------------------------------------
#define CVAR_QUERY_INTERFACE_VERSION "VCvarQuery001"
abstract_class ICvarQuery : public IAppSystem
{
public:
// Can these two convars be aliased?
virtual bool AreConVarsLinkable(const ConVar * child, const ConVar * parent) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: DLL interface to ConVars/ConCommands
//-----------------------------------------------------------------------------
abstract_class ICvar : public IAppSystem
{
public:
// Allocate a unique DLL identifier
virtual CVarDLLIdentifier_t AllocateDLLIdentifier() = 0;
// Register, unregister commands
virtual void RegisterConCommand( ConCommandBase *pCommandBase ) = 0;
virtual void UnregisterConCommand( ConCommandBase *pCommandBase ) = 0;
virtual void UnregisterConCommands( CVarDLLIdentifier_t id ) = 0;
virtual void sub_14062B1F0() = 0;
// If there is a +<varname> <value> on the command line, this returns the value.
// Otherwise, it returns NULL.
virtual const char* GetCommandLineValue( const char *pVariableName ) = 0;
// Try to find the cvar pointer by name
virtual ConCommandBase *FindCommandBase( const char *name ) = 0;
virtual const ConCommandBase *FindCommandBase( const char *name ) const = 0;
virtual ConVar *FindVar ( const char *var_name ) = 0;
virtual const ConVar *FindVar ( const char *var_name ) const = 0;
virtual ConCommand *FindCommand( const char *name ) = 0;
virtual const ConCommand *FindCommand( const char *name ) const = 0;
virtual void sub_140599640() = 0;
virtual void sub_140599BA0() = 0;
// Install a global change callback (to be called when any convar changes)
virtual void InstallGlobalChangeCallback(FnChangeCallback_t callback) = 0;
virtual void RemoveGlobalChangeCallback(FnChangeCallback_t callback) = 0;
virtual void CallGlobalChangeCallbacks(ConVar* var, const char* pOldString/*, float flOldValue*/) = 0;
// Install a console printer
virtual void InstallConsoleDisplayFunc(IConsoleDisplayFunc* pDisplayFunc) = 0;
virtual void RemoveConsoleDisplayFunc(IConsoleDisplayFunc* pDisplayFunc) = 0;
virtual void ConsoleColorPrintf(const Color& clr, PRINTF_FORMAT_STRING const char* pFormat, ...) const FMTFUNCTION(3, 4) = 0;
virtual void ConsolePrintf(PRINTF_FORMAT_STRING const char* pFormat, ...) const FMTFUNCTION(2, 3) = 0;
virtual void ConsoleDPrintf(PRINTF_FORMAT_STRING const char* pFormat, ...) const FMTFUNCTION(2, 3) = 0;
virtual void sub_140598730() = 0;
// Method allowing the engine ICvarQuery interface to take over
// A little hacky, owing to the fact the engine is loaded
// well after ICVar, so we can't use the standard connect pattern
virtual void InstallCVarQuery( ICvarQuery *pQuery ) = 0;
virtual void SetMaxSplitScreenSlots(int nSlots) = 0;
virtual int GetMaxSplitScreenSlots() const = 0;
virtual int GetConsoleDisplayFuncCount() const = 0;
virtual void GetConsoleText(int nDisplayFuncIndex, char* pchText, size_t bufSize) const = 0;
// Utilities for convars accessed by the material system thread
virtual bool IsMaterialThreadSetAllowed() const = 0;
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue) = 0;
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, int nValue) = 0;
virtual void QueueMaterialThreadSetValue(ConVar* pConVar, float flValue) = 0;
virtual bool HasQueuedMaterialThreadConVarSets() const = 0;
virtual int ProcessQueuedMaterialThreadConVarSets() = 0;
protected:
class ICVarIteratorInternal
{
public:
virtual void SetFirst(void) = 0;
virtual void Next(void) = 0;
virtual bool IsValid(void) = 0;
virtual ConCommandBase* Get(void) = 0;
};
virtual ICVarIteratorInternal* FactoryInternalIterator(void) = 0;
}; };
#endif // ICVAR_H #endif // ICVAR_H

View File

@ -32,6 +32,14 @@ ConVar* ConVar::Create(const char* pszName, const char* pszDefaultValue, int nFl
return pNewConVar; return pNewConVar;
} }
//-----------------------------------------------------------------------------
// Purpose: destroy
//-----------------------------------------------------------------------------
void ConVar::Destroy(void)
{
v_ConVar_Unregister(this);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: construct/allocate // Purpose: construct/allocate
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -12,6 +12,8 @@ class ConVar : public ConCommandBase
public: public:
static ConVar* Create(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString, static ConVar* Create(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString,
bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString); bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString);
void Destroy(void);
ConVar(void); ConVar(void);
~ConVar(void); ~ConVar(void);
@ -96,12 +98,15 @@ public:
static_assert(sizeof(ConVar) == 0xA0); static_assert(sizeof(ConVar) == 0xA0);
/* ==== ICONVAR ========================================================================================================================================================= */ /* ==== ICONVAR ========================================================================================================================================================= */
inline CMemory p_ConVar_IsFlagSet;
inline auto v_ConVar_IsFlagSet = p_ConVar_IsFlagSet.RCast<bool (*)(ConVar* pConVar, int nFlag)>();
inline CMemory p_ConVar_Register; inline CMemory p_ConVar_Register;
inline auto v_ConVar_Register = p_ConVar_Register.RCast<void* (*)(ConVar* thisptr, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString)>(); inline auto v_ConVar_Register = p_ConVar_Register.RCast<void* (*)(ConVar* thisptr, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t pCallback, const char* pszUsageString)>();
inline CMemory p_ConVar_Unregister;
inline auto v_ConVar_Unregister = p_ConVar_Unregister.RCast<void (*)(ConVar* thisptr)>();
inline CMemory p_ConVar_IsFlagSet;
inline auto v_ConVar_IsFlagSet = p_ConVar_IsFlagSet.RCast<bool (*)(ConVar* pConVar, int nFlag)>();
inline CMemory p_ConVar_PrintDescription; inline CMemory p_ConVar_PrintDescription;
inline auto v_ConVar_PrintDescription = p_ConVar_PrintDescription.RCast<void* (*)(ConCommandBase* pVar)>(); inline auto v_ConVar_PrintDescription = p_ConVar_PrintDescription.RCast<void* (*)(ConCommandBase* pVar)>();
@ -118,23 +123,27 @@ class VConVar : public IDetour
{ {
LogConAdr("ConVar::`vbtable'", g_pConVarVBTable.GetPtr()); LogConAdr("ConVar::`vbtable'", g_pConVarVBTable.GetPtr());
LogConAdr("ConVar::`vftable'", g_pConVarVFTable.GetPtr()); LogConAdr("ConVar::`vftable'", g_pConVarVFTable.GetPtr());
LogFunAdr("ConVar::IsFlagSet", p_ConVar_IsFlagSet.GetPtr());
LogFunAdr("ConVar::Register", p_ConVar_Register.GetPtr()); LogFunAdr("ConVar::Register", p_ConVar_Register.GetPtr());
LogFunAdr("ConVar::Unregister", p_ConVar_Unregister.GetPtr());
LogFunAdr("ConVar::IsFlagSet", p_ConVar_IsFlagSet.GetPtr());
LogFunAdr("ConVar_PrintDescription", p_ConVar_PrintDescription.GetPtr()); LogFunAdr("ConVar_PrintDescription", p_ConVar_PrintDescription.GetPtr());
} }
virtual void GetFun(void) const virtual void GetFun(void) const
{ {
p_ConVar_IsFlagSet = g_GameDll.FindPatternSIMD("48 8B 41 48 85 50 38");
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 F3 0F 10 44 24 ??"); p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 F3 0F 10 44 24 ??");
p_ConVar_Unregister = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 59 58 48 8D 05 ?? ?? ?? ??");
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 40 F3 0F 10 84 24 ?? ?? ?? ??"); p_ConVar_Register = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 40 F3 0F 10 84 24 ?? ?? ?? ??");
p_ConVar_Unregister = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 79 58");
#endif #endif
p_ConVar_IsFlagSet = g_GameDll.FindPatternSIMD("48 8B 41 48 85 50 38");
p_ConVar_PrintDescription = g_GameDll.FindPatternSIMD("B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 01 48 89 9C 24 ?? ?? ?? ??"); p_ConVar_PrintDescription = g_GameDll.FindPatternSIMD("B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B 01 48 89 9C 24 ?? ?? ?? ??");
v_ConVar_IsFlagSet = p_ConVar_IsFlagSet.RCast<bool (*)(ConVar*, int)>(); /*48 8B 41 48 85 50 38*/ v_ConVar_IsFlagSet = p_ConVar_IsFlagSet.RCast<bool (*)(ConVar*, int)>();
v_ConVar_Register = p_ConVar_Register.RCast<void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, FnChangeCallback_t, const char*)>(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 40 F3 0F 10 84 24 ? ? ? ?*/ v_ConVar_Register = p_ConVar_Register.RCast<void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, FnChangeCallback_t, const char*)>();
v_ConVar_PrintDescription = p_ConVar_PrintDescription.RCast<void* (*)(ConCommandBase*)>(); /*B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 48 8B 01 48 89 9C 24 ? ? ? ?*/ v_ConVar_Unregister = p_ConVar_Unregister.RCast<void (*)(ConVar*)>();
v_ConVar_PrintDescription = p_ConVar_PrintDescription.RCast<void* (*)(ConCommandBase*)>();
} }
virtual void GetVar(void) const { } virtual void GetVar(void) const { }
virtual void GetCon(void) const virtual void GetCon(void) const

View File

@ -696,98 +696,6 @@ int CCvarUtilities::CvarFindFlagsCompletionCallback(const char* partial, char co
return values; return values;
} }
//-----------------------------------------------------------------------------
// Purpose: registers input commands.
// Input : *pszCommandName -
//-----------------------------------------------------------------------------
ConCommandBase* CCvar::RegisterConCommand(ConCommandBase* pCommandToRemove)
{
const static int index = 9;
return CallVFunc<ConCommandBase*>(index, this, pCommandToRemove);
}
//-----------------------------------------------------------------------------
// Purpose: unregisters input commands.
// Input : *pszCommandName -
//-----------------------------------------------------------------------------
ConCommandBase* CCvar::UnregisterConCommand(ConCommandBase* pCommandToRemove)
{
const static int index = 10;
return CallVFunc<ConCommandBase*>(index, this, pCommandToRemove);
}
//-----------------------------------------------------------------------------
// Purpose: finds base commands.
// Input : *pszCommandName -
//-----------------------------------------------------------------------------
ConCommandBase* CCvar::FindCommandBase(const char* pszCommandName)
{
const static int index = 14;
return CallVFunc<ConCommandBase*>(index, this, pszCommandName);
}
//-----------------------------------------------------------------------------
// Purpose: finds ConVars.
// Input : *pszVarName -
//-----------------------------------------------------------------------------
ConVar* CCvar::FindVar(const char* pszVarName)
{
const static int index = 16;
return CallVFunc<ConVar*>(index, this, pszVarName);
}
//-----------------------------------------------------------------------------
// Purpose: finds ConCommands.
// Input : *pszCommandName -
//-----------------------------------------------------------------------------
ConCommand* CCvar::FindCommand(const char* pszCommandName)
{
const static int index = 18;
return CallVFunc<ConCommand*>(index, this, pszCommandName);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCvar::CallGlobalChangeCallbacks(ConVar* pConVar, const char* pOldString)
{
const static int index = 23;
CallVFunc<void>(index, this, pConVar, pOldString);
}
//-----------------------------------------------------------------------------
// Purpose: deal with queued material system ConVars
//-----------------------------------------------------------------------------
bool CCvar::IsMaterialThreadSetAllowed(void)
{
const static int index = 35;
return CallVFunc<bool>(index, this);
}
void CCvar::QueueMaterialThreadSetValue(ConVar* pConVar, float flValue)
{
const static int index = 36;
CallVFunc<void>(index, this, pConVar, flValue);
}
void CCvar::QueueMaterialThreadSetValue(ConVar* pConVar, int nValue)
{
const static int index = 37;
CallVFunc<void>(index, this, pConVar, nValue);
}
void CCvar::QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue)
{
const static int index = 38;
CallVFunc<void>(index, this, pConVar, pValue);
}
//-----------------------------------------------------------------------------
// Purpose: iterates over all ConVars
//-----------------------------------------------------------------------------
CCvar::CCVarIteratorInternal* CCvar::FactoryInternalIterator(void)
{
const static int index = 41;
return CallVFunc<CCVarIteratorInternal*>(index, this);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: returns all ConVars // Purpose: returns all ConVars
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -260,38 +260,10 @@ private:
extern CCvarUtilities* cv; extern CCvarUtilities* cv;
class CCvar // TODO: interface class !!! class CCvar : public CBaseAppSystem< ICvar >
{ { // Implementation in engine.
public: public:
ConCommandBase* RegisterConCommand(ConCommandBase* pCommandToAdd);
ConCommandBase* UnregisterConCommand(ConCommandBase* pCommandToRemove);
ConCommandBase* FindCommandBase(const char* pszCommandName); // @0x1405983A0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
ConVar* FindVar(const char* pszVarName); // @0x1405983B0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
ConCommand* FindCommand(const char* pszCommandName);
ConCommandBase* GetCommands(void) const { return m_pConCommandList; };
void CallGlobalChangeCallbacks(ConVar* pConVar, const char* pOldString);
bool IsMaterialThreadSetAllowed(void);
void QueueMaterialThreadSetValue(ConVar* pConVar, float flValue);
void QueueMaterialThreadSetValue(ConVar* pConVar, int nValue);
void QueueMaterialThreadSetValue(ConVar* pConVar, const char* pValue);
class CCVarIteratorInternal : public ICVarIteratorInternal
{
public:
virtual void SetFirst(void) = 0; //0
virtual void Next(void) = 0; //1
virtual bool IsValid(void) = 0; //2
virtual ConCommandBase* Get(void) = 0; //3
CCvar* const m_pOuter;
CConCommandHash* const m_pHash;
CConCommandHash::CCommandHashIterator_t m_hashIter;
};
CCVarIteratorInternal* FactoryInternalIterator(void);
unordered_map<string, ConCommandBase*> DumpToMap(void); unordered_map<string, ConCommandBase*> DumpToMap(void);
friend class CCVarIteratorInternal;
protected: protected:
enum ConVarSetType_t enum ConVarSetType_t
@ -310,8 +282,25 @@ protected:
//CUtlString m_String; // !TODO: //CUtlString m_String; // !TODO:
}; };
class CCVarIteratorInternal : public ICVarIteratorInternal
{
public:
virtual void SetFirst(void) = 0; //0
virtual void Next(void) = 0; //1
virtual bool IsValid(void) = 0; //2
virtual ConCommandBase* Get(void) = 0; //3
CCvar* const m_pOuter;
CConCommandHash* const m_pHash;
CConCommandHash::CCommandHashIterator_t m_hashIter;
};
virtual CCVarIteratorInternal* FactoryInternalIterator(void) = 0;
friend class CCVarIteratorInternal;
friend class CCvarUtilities;
private: private:
void* m_pVFTable;
CUtlVector< FnChangeCallback_t > m_GlobalChangeCallbacks; CUtlVector< FnChangeCallback_t > m_GlobalChangeCallbacks;
char pad0[30]; //!TODO: char pad0[30]; //!TODO:
int m_nNextDLLIdentifier; int m_nNextDLLIdentifier;