Improve ConVar class + rebuild ConCommand class

This commit is contained in:
Amos 2022-02-21 17:56:31 +01:00
parent ae0b439a3c
commit 9b8dfee460
4 changed files with 135 additions and 116 deletions

View File

@ -14,20 +14,16 @@
//-----------------------------------------------------------------------------
// Purpose: construct/allocate
//-----------------------------------------------------------------------------
ConVar::ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString, bool bMin, float fMin, bool bMax, float fMax, void* pCallback, void* unk)
ConVar::ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString, bool bMin, float fMin, bool bMax, float fMax, void* pCallback, const char* pszUsageString)
{
// Here we should make a proper constructor so we don't need casts etc. Maybe make a custom class/struct or use existing one, and then use register function at bottom.
ConVar* allocatedConvar = reinterpret_cast<ConVar*>(MemAlloc_Wrapper(0xA0)); // Allocate new memory with StdMemAlloc else we crash.
memset(allocatedConvar, 0, 0xA0); // Set all to null.
std::uintptr_t cvarPtr = reinterpret_cast<std::uintptr_t>(allocatedConvar); // To ptr.
ConVar* pNewConVar = reinterpret_cast<ConVar*>(MemAlloc_Wrapper(sizeof(ConVar))); // Allocate new memory with StdMemAlloc else we crash.
memset(pNewConVar, '\0', sizeof(ConVar)); // Set all to null.
*(void**)(cvarPtr + 0x40) = g_pIConVarVtable.RCast<void*>(); // 0x40 to ICvar table.
*(void**)cvarPtr = g_pConVarVtable.RCast<void*>(); // 0x0 to ConVar vtable.
pNewConVar->m_ConCommandBase.m_pConCommandBaseVTable = g_pConVarVtable.RCast<void*>();
pNewConVar->m_pIConVarVTable = g_pIConVarVtable.RCast<void*>();
p_ConVar_Register.RCast<void(*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, void*, void*)>()
(allocatedConvar, pszName, pszDefaultValue, nFlags, pszHelpString, bMin, fMin, bMax, fMax, pCallback, unk); // Call to create ConVar.
*this = *allocatedConvar;
ConVar_Register(pNewConVar, pszName, pszDefaultValue, nFlags, pszHelpString, bMin, fMin, bMax, fMax, pCallback, pszUsageString);
*this = *pNewConVar;
}
//-----------------------------------------------------------------------------
@ -35,10 +31,10 @@ ConVar::ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, con
//-----------------------------------------------------------------------------
ConVar::~ConVar(void)
{
if (m_pzsCurrentValue)
if (m_Value.m_pszString)
{
delete[] m_pzsCurrentValue;
m_pzsCurrentValue = NULL;
delete[] m_Value.m_pszString;
m_Value.m_pszString = NULL;
}
}
@ -190,7 +186,7 @@ bool ConVar::GetBool(void) const
//-----------------------------------------------------------------------------
float ConVar::GetFloat(void) const
{
return m_pParent->m_flValue;
return m_pParent->m_Value.m_fValue;
}
//-----------------------------------------------------------------------------
@ -199,7 +195,7 @@ float ConVar::GetFloat(void) const
//-----------------------------------------------------------------------------
int ConVar::GetInt(void) const
{
return m_pParent->m_iValue;
return m_pParent->m_Value.m_nValue;
}
//-----------------------------------------------------------------------------
@ -208,7 +204,7 @@ int ConVar::GetInt(void) const
//-----------------------------------------------------------------------------
Color ConVar::GetColor(void) const
{
unsigned char* pColorElement = ((unsigned char*)&m_pParent->m_iValue);
unsigned char* pColorElement = ((unsigned char*)&m_pParent->m_Value.m_nValue);
return Color(pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3]);
}
@ -223,7 +219,7 @@ const char* ConVar::GetString(void) const
return "FCVAR_NEVER_AS_STRING";
}
char const* str = m_pParent->m_pzsCurrentValue;
char const* str = m_pParent->m_Value.m_pszString;
return str ? str : "";
}
@ -234,7 +230,7 @@ const char* ConVar::GetString(void) const
//-----------------------------------------------------------------------------
bool ConVar::GetMin(float& flMinVal) const
{
flMinVal = m_pParent->m_flMinValue;
flMinVal = m_pParent->m_fMinVal;
return m_pParent->m_bHasMin;
}
@ -245,7 +241,7 @@ bool ConVar::GetMin(float& flMinVal) const
//-----------------------------------------------------------------------------
bool ConVar::GetMax(float& flMaxVal) const
{
flMaxVal = m_pParent->m_flMaxValue;
flMaxVal = m_pParent->m_fMaxVal;
return m_pParent->m_bHasMax;
}
@ -255,7 +251,7 @@ bool ConVar::GetMax(float& flMaxVal) const
//-----------------------------------------------------------------------------
float ConVar::GetMinValue(void) const
{
return m_pParent->m_flMinValue;
return m_pParent->m_fMinVal;
}
//-----------------------------------------------------------------------------
@ -264,7 +260,7 @@ float ConVar::GetMinValue(void) const
//-----------------------------------------------------------------------------
float ConVar::GetMaxValue(void) const
{
return m_pParent->m_flMaxValue;
return m_pParent->m_fMaxVal;
}
//-----------------------------------------------------------------------------
@ -291,7 +287,7 @@ bool ConVar::HasMax(void) const
//-----------------------------------------------------------------------------
void ConVar::SetValue(int nValue)
{
if (nValue == m_iValue)
if (nValue == m_Value.m_nValue)
{
return;
}
@ -308,14 +304,14 @@ void ConVar::SetValue(int nValue)
}
// Redetermine value.
float flOldValue = m_flValue;
m_flValue = flValue;
m_iValue = nValue;
float flOldValue = m_Value.m_fValue;
m_Value.m_fValue = flValue;
m_Value.m_fValue = nValue;
if (!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING))
{
char szTempValue[32];
snprintf(szTempValue, sizeof(szTempValue), "%d", m_iValue);
snprintf(szTempValue, sizeof(szTempValue), "%d", m_Value.m_nValue);
ChangeStringValue(szTempValue, flOldValue);
}
}
@ -326,7 +322,7 @@ void ConVar::SetValue(int nValue)
//-----------------------------------------------------------------------------
void ConVar::SetValue(float flValue)
{
if (flValue == m_flValue)
if (flValue == m_Value.m_fValue)
{
return;
}
@ -338,14 +334,14 @@ void ConVar::SetValue(float flValue)
ClampValue(flValue);
// Redetermine value.
float flOldValue = m_flValue;
m_flValue = flValue;
m_iValue = (int)m_flValue;
float flOldValue = m_Value.m_fValue;
m_Value.m_fValue = flValue;
m_Value.m_nValue = (int)m_Value.m_fValue;
if (!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING))
{
char szTempValue[32];
snprintf(szTempValue, sizeof(szTempValue), "%f", m_flValue);
snprintf(szTempValue, sizeof(szTempValue), "%f", m_Value.m_fValue);
ChangeStringValue(szTempValue, flOldValue);
}
}
@ -356,11 +352,11 @@ void ConVar::SetValue(float flValue)
//-----------------------------------------------------------------------------
void ConVar::SetValue(const char* pszValue)
{
if (strcmp(this->m_pParent->m_pzsCurrentValue, pszValue) == 0)
if (strcmp(this->m_pParent->m_Value.m_pszString, pszValue) == 0)
{
return;
}
this->m_pParent->m_pzsCurrentValue = pszValue;
this->m_pParent->m_Value.m_pszString = pszValue;
char szTempValue[32]{};
const char* pszNewValue{};
@ -368,7 +364,7 @@ void ConVar::SetValue(const char* pszValue)
// Only valid for root convars.
assert(m_pParent == this);
float flOldValue = m_flValue;
float flOldValue = m_Value.m_fValue;
pszNewValue = (char*)pszValue;
if (!pszNewValue)
{
@ -392,8 +388,8 @@ void ConVar::SetValue(const char* pszValue)
}
// Redetermine value
m_flValue = flNewValue;
m_iValue = (int)(m_flValue);
m_Value.m_fValue = flNewValue;
m_Value.m_nValue = (int)(m_Value.m_fValue);
}
if (!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING))
@ -419,7 +415,7 @@ void ConVar::SetValue(Color clValue)
}
}
this->m_pParent->m_pzsCurrentValue = svResult.c_str();
this->m_pParent->m_Value.m_pszString = svResult.c_str();
}
@ -459,32 +455,32 @@ void ConVar::ChangeStringValue(const char* pszTempVal, float flOldValue)
{
assert(!(m_ConCommandBase.m_nFlags & FCVAR_NEVER_AS_STRING));
char* pszOldValue = (char*)_malloca(m_iStringLength);
char* pszOldValue = (char*)_malloca(m_Value.m_iStringLength);
if (pszOldValue != NULL)
{
memcpy(pszOldValue, m_pzsCurrentValue, m_iStringLength);
memcpy(pszOldValue, m_Value.m_pszString, m_Value.m_iStringLength);
}
if (pszTempVal)
{
int len = strlen(pszTempVal) + 1;
if (len > m_iStringLength)
if (len > m_Value.m_iStringLength)
{
if (m_pzsCurrentValue)
if (m_Value.m_pszString)
{
delete[] m_pzsCurrentValue;
delete[] m_Value.m_pszString;
}
m_pzsCurrentValue = new char[len];
m_iStringLength = len;
m_Value.m_pszString = new char[len];
m_Value.m_iStringLength = len;
}
memcpy((char*)m_pzsCurrentValue, pszTempVal, len);
memcpy((char*)m_Value.m_pszString, pszTempVal, len);
}
else
{
m_pzsCurrentValue = NULL;
m_Value.m_pszString = NULL;
}
pszOldValue = 0;
@ -522,14 +518,14 @@ bool ConVar::SetColorFromString(const char* pszValue)
bColor = true;
// Stuff all the values into each byte of our int.
unsigned char* pColorElement = ((unsigned char*)&m_iValue);
unsigned char* pColorElement = ((unsigned char*)&m_Value.m_nValue);
pColorElement[0] = nRGBA[0];
pColorElement[1] = nRGBA[1];
pColorElement[2] = nRGBA[2];
pColorElement[3] = nRGBA[3];
// Copy that value into our float.
m_flValue = (float)(m_iValue);
m_Value.m_fValue = (float)(m_Value.m_nValue);
}
}
@ -543,15 +539,15 @@ bool ConVar::SetColorFromString(const char* pszValue)
//-----------------------------------------------------------------------------
bool ConVar::ClampValue(float& flValue)
{
if (m_bHasMin && (flValue < m_flMinValue))
if (m_bHasMin && (flValue < m_fMinVal))
{
flValue = m_flMinValue;
flValue = m_fMinVal;
return true;
}
if (m_bHasMax && (flValue > m_flMaxValue))
if (m_bHasMax && (flValue > m_fMaxVal))
{
flValue = m_flMaxValue;
flValue = m_fMaxVal;
return true;
}
@ -632,7 +628,7 @@ void ConVar::ClearHostNames(void)
if (pCVar != nullptr)
{
pCVar->m_pzsCurrentValue = "0.0.0.0";
pCVar->m_Value.m_pszString = "0.0.0.0";
}
}
}

View File

@ -87,7 +87,7 @@ class ConVar
public:
ConVar(void){};
ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, const char*pszHelpString,
bool bMin, float fMin, bool bMax, float fMax, void* pCallback, void* unk);
bool bMin, float fMin, bool bMax, float fMax, void* pCallback, const char* pszUsageString);
~ConVar(void);
void Init(void) const;
@ -130,18 +130,23 @@ public:
static bool IsFlagSet(ConVar* pConVar, int nFlags);
void ClearHostNames(void);
struct CVValue_t
{
const char* m_pszString;
int64_t m_iStringLength;
float m_fValue;
int m_nValue;
};
ConCommandBase m_ConCommandBase {}; //0x0000
void* m_pConVarVTable {}; //0x0040
void* m_pIConVarVTable {}; //0x0040
ConVar* m_pParent {}; //0x0048
const char* m_pszDefaultValue{}; //0x0050
const char* m_pzsCurrentValue{}; //0x0058
std::int64_t m_iStringLength {}; //0x0060
float m_flValue {}; //0x0068
int m_iValue {}; //0x006C
CVValue_t m_Value {}; //0c0058
bool m_bHasMin {}; //0x0070
float m_flMinValue {}; //0x0074
float m_fMinVal {}; //0x0074
bool m_bHasMax {}; //0x0078
float m_flMaxValue {}; //0x007C
float m_fMaxVal {}; //0x007C
char pad_0080[32] {}; //0x0080
}; //Size: 0x00A0
@ -158,7 +163,7 @@ namespace
void* (*ConVar_Register)(ConVar* allocatedConvar, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, void* pCallback, void* unk) = (void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, void*, void*))p_ConVar_Register.GetPtr();
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
ADDRESS p_ConVar_Register = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x40\xF3\x0F\x10\x84\x24\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxxxxxxxx????"); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 40 F3 0F 10 84 24 ? ? ? ?*/
void* (*ConVar_Register)(ConVar* allocatedConvar, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, void* pCallback, void* unk) = (void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, void*, void*))p_ConVar_Register.GetPtr();
void* (*ConVar_Register)(ConVar* allocatedConvar, const char* szName, const char* szDefaultValue, int nFlags, const char* szHelpString, bool bMin, float fMin, bool bMax, float fMax, void* pCallback, const char* pszUsageString) = (void* (*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, void*, const char*))p_ConVar_Register.GetPtr();
#endif
}

View File

@ -75,29 +75,25 @@ const char* CCommand::operator[](int nIndex) const
//-----------------------------------------------------------------------------
ConCommand::ConCommand(const char* pszName, const char* pszHelpString, int nFlags, void* pCallback, void* pCommandCompletionCallback)
{
ConCommand* pCommand = reinterpret_cast<ConCommand*>(MemAlloc_Wrapper(0x68)); // Allocate new memory with StdMemAlloc else we crash.
memset(pCommand, 0, 0x68); // Set all to null.
std::uintptr_t pCommandBase = reinterpret_cast<std::uintptr_t>(pCommand); // To ptr.
ConCommand* pCommand = reinterpret_cast<ConCommand*>(MemAlloc_Wrapper(sizeof(ConCommand))); // Allocate new memory with StdMemAlloc else we crash.
memset(pCommand, '\0', sizeof(ConCommand)); // Set all to null.
*(void**)pCommandBase = g_pConCommandVtable.RCast<void*>(); // 0x00 to ConCommand vtable.
*(const char**)(pCommandBase + 0x18) = pszName; // 0x18 to ConCommand Name.
*(const char**)(pCommandBase + 0x20) = pszHelpString; // 0x20 to ConCommand help string.
*(std::int32_t*)(pCommandBase + 0x38) = nFlags; // 0x38 to ConCommand Flags.
*(void**)(pCommandBase + 0x40) = p_ConCommand_NullSub.RCast<void*>(); // 0x40 Nullsub since every concommand has it.
*(void**)(pCommandBase + 0x50) = pCallback; // 0x50 has function callback.
*(std::int32_t*)(pCommandBase + 0x60) = 2; // 0x60 Set to use callback and newcommand callback.
if (pCommandCompletionCallback) // callback after execution desired?
pCommand->m_ConCommandBase.m_pConCommandBaseVTable = g_pConCommandVtable.RCast<void*>();
pCommand->m_ConCommandBase.m_pszName = pszName;
pCommand->m_ConCommandBase.m_pszHelpString = pszHelpString;
pCommand->m_ConCommandBase.m_nFlags = nFlags;
pCommand->m_nNullCallBack = NullSub;
pCommand->m_pCommandCallback = pCallback;
pCommand->m_nCallbackFlags = 2;
if (pCommandCompletionCallback)
{
*(void**)(pCommandBase + 0x58) = pCommandCompletionCallback; // 0x58 to our callback after execution.
pCommand->m_pCompletionCallback = pCommandCompletionCallback;
}
else
{
*(void**)(pCommandBase + 0x58) = p_ConCommand_CallbackCompletion.RCast<void*>(); // 0x58 nullsub.
pCommand->m_pCompletionCallback = CallbackStub;
}
p_ConCommand_RegisterConCommand.RCast<void(*)(void*)>()((void*)pCommandBase); // Register command in ConVarAccessor.
ConCommand_RegisterConCommand(pCommand);
*this = *pCommand;
}

View File

@ -1,5 +1,22 @@
#pragma once
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ConCommandBase;
//-----------------------------------------------------------------------------
// Any executable that wants to use ConVars need to implement one of
// these to hook up access to console variables.
//-----------------------------------------------------------------------------
class IConCommandBaseAccessor
{
public:
// Flags is a combination of FCVAR flags in cvar.h.
// hOut is filled in with a handle to the variable.
virtual bool RegisterConCommandBase(ConCommandBase* pVar) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Command buffer context
//-----------------------------------------------------------------------------
@ -57,19 +74,6 @@ private:
const char* m_ppArgv[COMMAND_MAX_ARGC];
};
//-----------------------------------------------------------------------------
// Purpose: The console invoked command
//-----------------------------------------------------------------------------
class ConCommand
{
friend class CCVar;
public:
ConCommand(void) {};
ConCommand(const char* szName, const char* szHelpString, int nFlags, void* pCallback, void* pCommandCompletionCallback);
void Init(void);
// TODO
};
//-----------------------------------------------------------------------------
// Purpose: The base console invoked command/cvar interface
//-----------------------------------------------------------------------------
@ -81,21 +85,37 @@ public:
bool HasFlags(int nFlags);
static bool IsFlagSet(ConCommandBase* pCommandBase, int nFlags);
void* m_pConCommandBaseVTable; //0x0000
ConCommandBase* m_pNext; //0x0008
bool m_bRegistered; //0x0010
private:
char pad_0011[7]; //0x0011
void* m_pConCommandBaseVTable; //0x0000
ConCommandBase* m_pNext; //0x0008
bool m_bRegistered; //0x0010
char pad_0011[7]; //0x0011
const char* m_pszName; //0x0018
const char* m_pszHelpString; //0x0020
const char* m_pszUsageString; //0x0028
IConCommandBaseAccessor* s_pAccessor; //0x0030 <-- unused since executable is monolithic.
int m_nFlags; //0x0038
char pad_003C[4]; //0x003C
}; //Size: 0x0040
//-----------------------------------------------------------------------------
// Purpose: The console invoked command
//-----------------------------------------------------------------------------
class ConCommand
{
friend class CCVar;
public:
const char* m_pszName; //0x0018
const char* m_pszHelpString; //0x0020
private:
char pad_0028[16]; //0x0028
public:
int m_nFlags; //0x0038
private:
char pad_003C[4]; //0x003C
}; //Size: 0x0038
ConCommand(void) {};
ConCommand(const char* szName, const char* szHelpString, int nFlags, void* pCallback, void* pCommandCompletionCallback);
void Init(void);
ConCommandBase m_ConCommandBase {}; //0x0000
void* m_nNullCallBack {}; //0x0040
char m_nPad48[8] {}; //0x0048
void* m_pCommandCallback {}; //0x0050
void* m_pCompletionCallback{}; //0x0058
int m_nCallbackFlags {}; //0x0060
char m_nPad68[4] {}; //0x0068
};
namespace
{
@ -113,14 +133,14 @@ namespace
ADDRESS p_ConCommand_CMaterialSystemCmdInit = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x83\xEC\x50\x48\x8B\x15\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxxxxx????");
ConCommand*(*ConCommand_CMaterialSystemCmdInit)() = (ConCommand* (*)())p_ConCommand_CMaterialSystemCmdInit.GetPtr();
ADDRESS p_ConCommand_NullSub = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xC2\x00\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxxxx????");
void (*ConCommand_NullSub)() = (void (*)())p_ConCommand_NullSub.GetPtr(); /*C2 00 00 CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/
ADDRESS p_ConCommand_CallbackCompletion = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x33\xC0\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x80\x49\x68\x08", "xxxxxxxxxxxxxxxxxxxx");
void* (*ConCommand_CallbackCompletion)(struct _exception* _exc) = (void* (*)(struct _exception*))p_ConCommand_CallbackCompletion.GetPtr(); /*33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08*/ /*UserMathErrorFunction*/
ADDRESS p_ConCommand_RegisterConCommand = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xD1\x48\x8B\x0D\x00\x00\x00\x00\x48\x85\xC9\x74\x06", "xxxxxx????xxxxx");
void* (*ConCommand_RegisterConCommand)(ConCommandBase* pCommandBase) = (void* (*)(ConCommandBase*))p_ConCommand_RegisterConCommand.GetPtr(); /*48 8B D1 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 06 */
void* (*ConCommand_RegisterConCommand)(ConCommand* pCommand) = (void* (*)(ConCommand*))p_ConCommand_RegisterConCommand.GetPtr(); /*48 8B D1 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 06*/
ADDRESS p_NullSub = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xC2\x00\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxxxx????");
void (*NullSub)() = (void (*)())p_NullSub.GetPtr(); /*C2 00 00 CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/
ADDRESS p_CallbackStub = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x33\xC0\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x80\x49\x68\x08", "xxxxxxxxxxxxxxxxxxxx");
void* (*CallbackStub)(struct _exception* _exc) = (void* (*)(struct _exception*))p_CallbackStub.GetPtr(); /*33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08*/ /*UserMathErrorFunction*/
static ADDRESS g_pConCommandVtable = p_ConCommand_CMaterialSystemCmdInit.FindPatternSelf("4C 8D 25", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7);
}
@ -141,9 +161,11 @@ class HConCommand : public IDetour
std::cout << "+----------------------------------------------------------------+" << std::endl;
std::cout << "| FUN: ConCommandBase::IsFlagSet : 0x" << std::hex << std::uppercase << p_ConCommandBase_IsFlagSet.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: ConCommand::CMaterialSystemCmdInit : 0x" << std::hex << std::uppercase << p_ConCommand_CMaterialSystemCmdInit.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: ConCommand::NullSub : 0x" << std::hex << std::uppercase << p_ConCommand_NullSub.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: ConCommand::CallbackCompletion : 0x" << std::hex << std::uppercase << p_ConCommand_CallbackCompletion.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: ConCommand::RegisterConCommand : 0x" << std::hex << std::uppercase << p_ConCommand_RegisterConCommand.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
std::cout << "| FUN: CallbackStub : 0x" << std::hex << std::uppercase << p_CallbackStub.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: NullSub : 0x" << std::hex << std::uppercase << p_NullSub.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
std::cout << "| VAR: g_pConCommandVtable : 0x" << std::hex << std::uppercase << g_pConCommandVtable.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
}