mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Implement convar_list and convar_differences
Also added more CCvarUtilities methods which are yet to be implemented.
This commit is contained in:
parent
aa72579656
commit
4551f6d494
@ -176,6 +176,68 @@ void HexDump(const char* szHeader, const char* szLogger, const void* pData, int
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For stripping tabs and return characters from input buffer.
|
||||
char* StripTabsAndReturns(const char* pInBuffer, char* pOutBuffer, int nOutBufferSize)
|
||||
{
|
||||
char* out = pOutBuffer;
|
||||
const char* i = pInBuffer;
|
||||
char* o = out;
|
||||
|
||||
out[0] = 0;
|
||||
|
||||
while (*i && o - out < nOutBufferSize - 1)
|
||||
{
|
||||
if (*i == '\n' ||
|
||||
*i == '\r' ||
|
||||
*i == '\t')
|
||||
{
|
||||
*o++ = ' ';
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (*i == '\"')
|
||||
{
|
||||
*o++ = '\'';
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*o++ = *i++;
|
||||
}
|
||||
|
||||
*o = '\0';
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For stripping quote characters from input buffer.
|
||||
char* StripQuotes(const char* pInBuffer, char* pOutBuffer, int nOutBufferSize)
|
||||
{
|
||||
char* out = pOutBuffer;
|
||||
const char* i = pInBuffer;
|
||||
char* o = out;
|
||||
|
||||
out[0] = 0;
|
||||
|
||||
while (*i && o - out < nOutBufferSize - 1)
|
||||
{
|
||||
if (*i == '\"')
|
||||
{
|
||||
*o++ = '\'';
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*o++ = *i++;
|
||||
}
|
||||
|
||||
*o = '\0';
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For checking if file name has a specific extension.
|
||||
bool HasExtension(const string& svInput, const string& svExtension)
|
||||
@ -728,6 +790,20 @@ void PrintM128i64(__m128i in)
|
||||
printf("v2_u64: %llx %llx\n", v[0], v[1]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For appending characters to a printf buffer.
|
||||
void AppendPrintf(char* pBuffer, size_t nBufSize, char const* pFormat, ...)
|
||||
{
|
||||
char scratch[1024];
|
||||
va_list argptr;
|
||||
va_start(argptr, pFormat);
|
||||
_vsnprintf(scratch, sizeof(scratch) - 1, pFormat, argptr);
|
||||
va_end(argptr);
|
||||
scratch[sizeof(scratch) - 1] = 0;
|
||||
|
||||
strncat(pBuffer, scratch, nBufSize);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For escaping the '%' character for *rintf.
|
||||
string PrintPercentageEscape(const string& svInput)
|
||||
|
@ -12,6 +12,11 @@ void DbgPrint(LPCSTR sFormat, ...);
|
||||
void PrintLastError(void);
|
||||
void HexDump(const char* szHeader, const char* szLogger, const void* pData, int nSize);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Char
|
||||
char* StripTabsAndReturns(const char* pInBuffer, char* pOutBuffer, int nOutBufferSize);
|
||||
char* StripQuotes(const char* pInBuffer, char* pOutBuffer, int nOutBufferSize);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// String
|
||||
bool HasExtension(const string& svInput, const string& svExtension);
|
||||
@ -58,6 +63,7 @@ void PrintM128i16(__m128i in);
|
||||
void PrintM128i32(__m128i in);
|
||||
void PrintM128i64(__m128i in);
|
||||
|
||||
void AppendPrintf(char* pBuffer, size_t nBufSize, char const* pFormat, ...);
|
||||
string PrintPercentageEscape(const string& svInput);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -534,7 +534,7 @@ void ConVar::SetValue(Color value)
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar::InternalSetValue(const char* pszValue)
|
||||
{
|
||||
if (IsFlagSet(this, FCVAR_MATERIAL_THREAD_MASK))
|
||||
if (IsFlagSet(FCVAR_MATERIAL_THREAD_MASK))
|
||||
{
|
||||
if (g_pCVar && !g_pCVar->IsMaterialThreadSetAllowed())
|
||||
{
|
||||
@ -593,7 +593,7 @@ void ConVar::InternalSetIntValue(int nValue)
|
||||
if (nValue == m_Value.m_nValue)
|
||||
return;
|
||||
|
||||
if (IsFlagSet(this, FCVAR_MATERIAL_THREAD_MASK))
|
||||
if (IsFlagSet(FCVAR_MATERIAL_THREAD_MASK))
|
||||
{
|
||||
if (g_pCVar && !g_pCVar->IsMaterialThreadSetAllowed())
|
||||
{
|
||||
@ -631,7 +631,7 @@ void ConVar::InternalSetFloatValue(float flValue)
|
||||
if (flValue == m_Value.m_fValue)
|
||||
return;
|
||||
|
||||
if (IsFlagSet(this, FCVAR_MATERIAL_THREAD_MASK))
|
||||
if (IsFlagSet(FCVAR_MATERIAL_THREAD_MASK))
|
||||
{
|
||||
if (g_pCVar && !g_pCVar->IsMaterialThreadSetAllowed())
|
||||
{
|
||||
@ -885,7 +885,7 @@ bool ConVar::IsCommand(void) const
|
||||
// Input : *pConVar - nFlags
|
||||
// Output : False if change is permitted, true if not.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConVar::IsFlagSet(ConVar* pConVar, int nFlags)
|
||||
bool ConVar::IsFlagSetInternal(ConVar* pConVar, int nFlags)
|
||||
{
|
||||
if (cm_debug_cmdquery->GetBool())
|
||||
{
|
||||
@ -924,12 +924,139 @@ bool ConVar::IsFlagSet(ConVar* pConVar, int nFlags)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void IConVar_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&IConVar_IsFlagSet, &ConVar::IsFlagSet);
|
||||
DetourAttach((LPVOID*)&IConVar_IsFlagSet, &ConVar::IsFlagSetInternal);
|
||||
}
|
||||
|
||||
void IConVar_Detach()
|
||||
{
|
||||
DetourDetach((LPVOID*)&IConVar_IsFlagSet, &ConVar::IsFlagSet);
|
||||
DetourDetach((LPVOID*)&IConVar_IsFlagSet, &ConVar::IsFlagSetInternal);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct PrintConVarFlags_t
|
||||
{
|
||||
int flag;
|
||||
const char* desc;
|
||||
};
|
||||
|
||||
static PrintConVarFlags_t g_PrintConVarFlags[] =
|
||||
{
|
||||
{ FCVAR_GAMEDLL, "game" },
|
||||
{ FCVAR_CLIENTDLL, "client" },
|
||||
{ FCVAR_ARCHIVE, "archive" },
|
||||
{ FCVAR_NOTIFY, "notify" },
|
||||
{ FCVAR_SPONLY, "singleplayer" },
|
||||
{ FCVAR_NOT_CONNECTED, "notconnected" },
|
||||
{ FCVAR_CHEAT, "cheat" },
|
||||
{ FCVAR_REPLICATED, "replicated" },
|
||||
{ FCVAR_SERVER_CAN_EXECUTE, "server_can_execute" },
|
||||
{ FCVAR_CLIENTCMD_CAN_EXECUTE, "clientcmd_can_execute" },
|
||||
{ FCVAR_USERINFO, "user" },
|
||||
{ FCVAR_SS, "ss" },
|
||||
{ FCVAR_SS_ADDED, "ss_added" },
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_AppendFlags(ConCommandBase* var, char* buf, size_t bufsize)
|
||||
{
|
||||
for (int i = 0; i < ARRAYSIZE(g_PrintConVarFlags); ++i)
|
||||
{
|
||||
const PrintConVarFlags_t& info = g_PrintConVarFlags[i];
|
||||
if (var->IsFlagSet(info.flag))
|
||||
{
|
||||
char append[128];
|
||||
snprintf(append, sizeof(append), " %s", info.desc);
|
||||
strncat(buf, append, bufsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConVar_PrintDescription(ConCommandBase* pVar)
|
||||
{
|
||||
bool bMin, bMax;
|
||||
float fMin, fMax;
|
||||
const char* pStr;
|
||||
|
||||
Assert(pVar);
|
||||
|
||||
Color clr(255, 100, 100, 255);
|
||||
|
||||
char outstr[4096];
|
||||
outstr[0] = 0;
|
||||
|
||||
if (!pVar->IsCommand())
|
||||
{
|
||||
ConVar* var = (ConVar*)pVar;
|
||||
|
||||
bMin = var->GetMin(fMin);
|
||||
bMax = var->GetMax(fMax);
|
||||
|
||||
const char* value = NULL;
|
||||
char tempVal[256];
|
||||
|
||||
if (var->IsFlagSet(FCVAR_NEVER_AS_STRING))
|
||||
{
|
||||
value = tempVal;
|
||||
|
||||
int intVal = var->GetInt();
|
||||
float floatVal = var->GetFloat();
|
||||
|
||||
if (fabs((float)intVal - floatVal) < 0.000001)
|
||||
{
|
||||
snprintf(tempVal, sizeof(tempVal), "%d", intVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(tempVal, sizeof(tempVal), "%f", floatVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = var->GetString();
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
AppendPrintf(outstr, sizeof(outstr), "\"%s\" = \"%s\"", var->GetName(), value);
|
||||
|
||||
if (_stricmp(value, var->GetDefault()))
|
||||
{
|
||||
AppendPrintf(outstr, sizeof(outstr), " ( def. \"%s\" )", var->GetDefault());
|
||||
}
|
||||
}
|
||||
|
||||
if (bMin)
|
||||
{
|
||||
AppendPrintf(outstr, sizeof(outstr), " min. %f", fMin);
|
||||
}
|
||||
if (bMax)
|
||||
{
|
||||
AppendPrintf(outstr, sizeof(outstr), " max. %f", fMax);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConCommand* var = (ConCommand*)pVar;
|
||||
|
||||
AppendPrintf(outstr, sizeof(outstr), "\"%s\" ", var->GetName());
|
||||
}
|
||||
|
||||
ConVar_AppendFlags(pVar, outstr, sizeof(outstr));
|
||||
|
||||
pStr = pVar->GetHelpText();
|
||||
if (pStr && *pStr)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%-80s - %.80s\n", outstr, pStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "%-80s\n", outstr);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -69,7 +69,9 @@ public:
|
||||
|
||||
bool IsRegistered(void) const;
|
||||
bool IsCommand(void) const;
|
||||
static bool IsFlagSet(ConVar* pConVar, int nFlags);
|
||||
|
||||
bool IsFlagSet(int nFlags) { return IsFlagSetInternal(this, nFlags); };
|
||||
static bool IsFlagSetInternal(ConVar* pConVar, int nFlags);
|
||||
|
||||
struct CVValue_t
|
||||
{
|
||||
@ -108,6 +110,8 @@ inline CMemory g_pIConVarVFTable;
|
||||
void IConVar_Attach();
|
||||
void IConVar_Detach();
|
||||
|
||||
void ConVar_PrintDescription(ConCommandBase* pVar);
|
||||
|
||||
extern ConVar* g_pConVar;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -373,6 +373,10 @@ void ConCommand::Init(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConCommand::InitShipped(void)
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// ENGINE DLL |
|
||||
g_pCVar->FindCommand("convar_list")->m_fnCommandCallback = CVList_f;
|
||||
g_pCVar->FindCommand("convar_differences")->m_fnCommandCallback = CVDiff_f;
|
||||
#ifndef DEDICATED
|
||||
//-------------------------------------------------------------------------
|
||||
// MATERIAL SYSTEM
|
||||
@ -477,7 +481,7 @@ bool ConCommandBase::IsRegistered(void) const
|
||||
// Input : *pCommandBase - nFlags
|
||||
// Output : False if execution is permitted, true if not.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConCommandBase::IsFlagSet(ConCommandBase* pCommandBase, int nFlags)
|
||||
bool ConCommandBase::IsFlagSetInternal(ConCommandBase* pCommandBase, int nFlags)
|
||||
{
|
||||
if (cm_debug_cmdquery->GetBool())
|
||||
{
|
||||
@ -518,7 +522,7 @@ bool ConCommandBase::IsFlagSet(ConCommandBase* pCommandBase, int nFlags)
|
||||
// Input : nFlags -
|
||||
// Output : True if ConCommand has nFlags.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConCommandBase::HasFlags(int nFlags)
|
||||
bool ConCommandBase::HasFlags(int nFlags) const
|
||||
{
|
||||
return m_nFlags & nFlags;
|
||||
}
|
||||
@ -623,10 +627,10 @@ ECommandTarget_t Cbuf_GetCurrentPlayer(void)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void ConCommand_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSet);
|
||||
DetourAttach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSetInternal);
|
||||
}
|
||||
void ConCommand_Detach()
|
||||
{
|
||||
DetourDetach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSet);
|
||||
DetourDetach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSetInternal);
|
||||
}
|
||||
ConCommand* g_pConCommand = new ConCommand();
|
||||
|
@ -89,13 +89,15 @@ private:
|
||||
class ConCommandBase
|
||||
{
|
||||
public:
|
||||
bool HasFlags(int nFlags);
|
||||
bool HasFlags(int nFlags) const;
|
||||
void AddFlags(int nFlags);
|
||||
void RemoveFlags(int nFlags);
|
||||
|
||||
bool IsCommand(void) const;
|
||||
bool IsRegistered(void) const;
|
||||
static bool IsFlagSet(ConCommandBase* pCommandBase, int nFlags);
|
||||
|
||||
bool IsFlagSet(int nFlags) { return IsFlagSetInternal(this, nFlags); };
|
||||
static bool IsFlagSetInternal(ConCommandBase* pCommandBase, int nFlags);
|
||||
|
||||
int GetFlags(void) const;
|
||||
ConCommandBase* GetNext(void) const;
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/utlrbtree.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "tier1/IConVar.h"
|
||||
#include "engine/sys_dll2.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ENGINE |
|
||||
@ -166,6 +168,483 @@ ConVar* pylon_showdebug = nullptr;
|
||||
ConVar* rui_drawEnable = nullptr;
|
||||
#endif // !DEDICATED
|
||||
|
||||
struct ConVarFlags_t
|
||||
{
|
||||
int bit;
|
||||
const char* desc;
|
||||
const char* shortdesc;
|
||||
};
|
||||
|
||||
#define CONVARFLAG( x, y ) { FCVAR_##x, #x, #y }
|
||||
|
||||
static ConVarFlags_t g_ConVarFlags[] =
|
||||
{
|
||||
// CONVARFLAG( UNREGISTERED, "u" ),
|
||||
CONVARFLAG(ARCHIVE, "a"),
|
||||
CONVARFLAG(SPONLY, "sp"),
|
||||
CONVARFLAG(GAMEDLL, "sv"),
|
||||
CONVARFLAG(CHEAT, "cheat"),
|
||||
CONVARFLAG(USERINFO, "user"),
|
||||
CONVARFLAG(NOTIFY, "nf"),
|
||||
CONVARFLAG(PROTECTED, "prot"),
|
||||
CONVARFLAG(PRINTABLEONLY, "print"),
|
||||
CONVARFLAG(UNLOGGED, "log"),
|
||||
CONVARFLAG(NEVER_AS_STRING, "numeric"),
|
||||
CONVARFLAG(REPLICATED, "rep"),
|
||||
CONVARFLAG(DEMO, "demo"),
|
||||
CONVARFLAG(DONTRECORD, "norecord"),
|
||||
CONVARFLAG(SERVER_CAN_EXECUTE, "server_can_execute"),
|
||||
CONVARFLAG(CLIENTCMD_CAN_EXECUTE, "clientcmd_can_execute"),
|
||||
CONVARFLAG(CLIENTDLL, "cl"),
|
||||
};
|
||||
|
||||
static void PrintListHeader(FileHandle_t& f)
|
||||
{
|
||||
char csvflagstr[1024];
|
||||
|
||||
csvflagstr[0] = 0;
|
||||
|
||||
int c = ARRAYSIZE(g_ConVarFlags);
|
||||
for (int i = 0; i < c; ++i)
|
||||
{
|
||||
char csvf[64];
|
||||
|
||||
ConVarFlags_t& entry = g_ConVarFlags[i];
|
||||
snprintf(csvf, sizeof(csvf), "\"%s\",", entry.desc);
|
||||
strncat(csvflagstr, csvf, sizeof(csvflagstr));
|
||||
}
|
||||
|
||||
FileSystem()->FPrintf(f, "\"%s\",\"%s\",%s,\"%s\"\n", "Name", "Value", csvflagstr, "Help Text");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *var -
|
||||
// *f -
|
||||
//-----------------------------------------------------------------------------
|
||||
static void PrintCvar(ConVar* var, bool logging, FileHandle_t& fh)
|
||||
{
|
||||
char flagstr[128];
|
||||
char csvflagstr[1024];
|
||||
|
||||
flagstr[0] = 0;
|
||||
csvflagstr[0] = 0;
|
||||
|
||||
int c = ARRAYSIZE(g_ConVarFlags);
|
||||
for (int i = 0; i < c; ++i)
|
||||
{
|
||||
char f[32];
|
||||
char csvf[64];
|
||||
|
||||
ConVarFlags_t& entry = g_ConVarFlags[i];
|
||||
if (var->IsFlagSet(entry.bit))
|
||||
{
|
||||
snprintf(f, sizeof(f), ", %s", entry.shortdesc);
|
||||
strncat(flagstr, f, sizeof(flagstr));
|
||||
snprintf(csvf, sizeof(csvf), "\"%s\",", entry.desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(csvf, sizeof(csvf), ",");
|
||||
}
|
||||
|
||||
strncat(csvflagstr, csvf, sizeof(csvflagstr));
|
||||
}
|
||||
|
||||
|
||||
char valstr[32];
|
||||
char tempbuff[512] = { 0 };
|
||||
|
||||
// Clean up integers
|
||||
if (var->GetInt() == (int)var->GetFloat())
|
||||
{
|
||||
snprintf(valstr, sizeof(valstr), "%-8i", var->GetInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(valstr, sizeof(valstr), "%-8.3f", var->GetFloat());
|
||||
}
|
||||
|
||||
// Print to console
|
||||
DevMsg(eDLL_T::ENGINE, "%-40s : %-8s : %-16s : %s\n", var->GetName(), valstr, flagstr, StripTabsAndReturns(var->GetHelpText(), tempbuff, sizeof(tempbuff)));
|
||||
if (logging)
|
||||
{
|
||||
FileSystem()->FPrintf(fh, "\"%s\",\"%s\",%s,\"%s\"\n", var->GetName(), valstr, csvflagstr, StripQuotes(var->GetHelpText(), tempbuff, sizeof(tempbuff)));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
static void PrintCommand(const ConCommand* cmd, bool logging, FileHandle_t& f)
|
||||
{
|
||||
// Print to console
|
||||
char tempbuff[512] = { 0 };
|
||||
DevMsg(eDLL_T::ENGINE, "%-40s : %-8s : %-16s : %s\n", cmd->GetName(), "cmd", "", StripTabsAndReturns(cmd->GetHelpText(), tempbuff, sizeof(tempbuff)));
|
||||
if (logging)
|
||||
{
|
||||
char emptyflags[256];
|
||||
|
||||
emptyflags[0] = 0;
|
||||
|
||||
int c = ARRAYSIZE(g_ConVarFlags);
|
||||
for (int i = 0; i < c; ++i)
|
||||
{
|
||||
char csvf[64];
|
||||
Q_snprintf(csvf, sizeof(csvf), ",");
|
||||
Q_strncat(emptyflags, csvf, sizeof(emptyflags));
|
||||
}
|
||||
// Names staring with +/- need to be wrapped in single quotes
|
||||
char name[256];
|
||||
snprintf(name, sizeof(name), "%s", cmd->GetName());
|
||||
if (name[0] == '+' || name[0] == '-')
|
||||
{
|
||||
snprintf(name, sizeof(name), "'%s'", cmd->GetName());
|
||||
}
|
||||
FileSystem()->FPrintf(f, "\"%s\",\"%s\",%s,\"%s\"\n", name, "cmd", emptyflags, StripQuotes(cmd->GetHelpText(), tempbuff, sizeof(tempbuff)));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output : bool
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool ConCommandBaseLessFunc(ConCommandBase* const& lhs, ConCommandBase* const& rhs)
|
||||
{
|
||||
const char* left = lhs->GetName();
|
||||
const char* right = rhs->GetName();
|
||||
|
||||
if (*left == '-' || *left == '+')
|
||||
left++;
|
||||
if (*right == '-' || *right == '+')
|
||||
right++;
|
||||
|
||||
return (Q_stricmp(left, right) < 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton CCvarUtilities
|
||||
//-----------------------------------------------------------------------------
|
||||
static CCvarUtilities g_CvarUtilities;
|
||||
CCvarUtilities* cv = &g_CvarUtilities;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CCvarUtilities::CountVariablesWithFlags(int flags)
|
||||
{
|
||||
int i = 0;
|
||||
ConCommandBase* var;
|
||||
|
||||
// Loop through cvars...
|
||||
CCVarIteratorInternal* pFactory = g_pCVar->FactoryInternalIterator();
|
||||
pFactory->SetFirst();
|
||||
|
||||
while (pFactory->IsValid())
|
||||
{
|
||||
var = pFactory->Get();
|
||||
if (!var->IsCommand())
|
||||
{
|
||||
if (var->IsFlagSet(flags))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
pFactory->Next();
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Removes the FCVAR_DEVELOPMENTONLY flag from all cvars, making them accessible
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCvarUtilities::EnableDevCvars()
|
||||
{
|
||||
// Loop through cvars...
|
||||
CCVarIteratorInternal* pFactory = g_pCVar->FactoryInternalIterator();
|
||||
pFactory->SetFirst();
|
||||
|
||||
while (pFactory->IsValid())
|
||||
{
|
||||
// remove flag from all cvars
|
||||
ConCommandBase* pCommandBase = pFactory->Get();
|
||||
pCommandBase->RemoveFlags(FCVAR_DEVELOPMENTONLY);
|
||||
|
||||
pFactory->Next();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : void CCvar::CvarList_f
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCvarUtilities::CvarList(const CCommand& args)
|
||||
{
|
||||
ConCommandBase* var; // Temporary Pointer to cvars
|
||||
int iArgs; // Argument count
|
||||
const char* partial = NULL; // Partial cvar to search for...
|
||||
// E.eg
|
||||
int ipLen = 0; // Length of the partial cvar
|
||||
|
||||
FileHandle_t f = FILESYSTEM_INVALID_HANDLE; // FilePointer for logging
|
||||
bool bLogging = false;
|
||||
// Are we logging?
|
||||
iArgs = args.ArgC(); // Get count
|
||||
|
||||
// Print usage?
|
||||
if (iArgs == 2 && !Q_strcasecmp(args[1], "?"))
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "cvarlist: [log logfile] [ partial ]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Q_strcasecmp(args[1], "log") && iArgs >= 3)
|
||||
{
|
||||
char fn[256];
|
||||
Q_snprintf(fn, sizeof(fn), "%s", args[2]);
|
||||
f = FileSystem()->Open(fn, "wb", nullptr, 0);
|
||||
if (f)
|
||||
{
|
||||
bLogging = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "Couldn't open '%s' for writing!\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iArgs == 4)
|
||||
{
|
||||
partial = args[3];
|
||||
ipLen = Q_strlen(partial);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
partial = args[1];
|
||||
ipLen = Q_strlen(partial);
|
||||
}
|
||||
|
||||
// Banner
|
||||
DevMsg(eDLL_T::ENGINE, "cvar list\n--------------\n");
|
||||
|
||||
CUtlRBTree< ConCommandBase* > sorted(0, 0, ConCommandBaseLessFunc);
|
||||
|
||||
// Loop through cvars...
|
||||
CCVarIteratorInternal* pFactory = g_pCVar->FactoryInternalIterator();
|
||||
pFactory->SetFirst();
|
||||
|
||||
while (pFactory->IsValid())
|
||||
{
|
||||
var = pFactory->Get();
|
||||
|
||||
if (!var->IsFlagSet(FCVAR_DEVELOPMENTONLY) &&
|
||||
!var->IsFlagSet(FCVAR_HIDDEN))
|
||||
{
|
||||
bool print = false;
|
||||
|
||||
if (partial) // Partial string searching?
|
||||
{
|
||||
if (!Q_strncasecmp(var->GetName(), partial, ipLen))
|
||||
{
|
||||
print = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print = true;
|
||||
}
|
||||
|
||||
if (print)
|
||||
{
|
||||
sorted.Insert(var);
|
||||
}
|
||||
}
|
||||
pFactory->Next();
|
||||
}
|
||||
|
||||
if (bLogging)
|
||||
{
|
||||
PrintListHeader(f);
|
||||
}
|
||||
for (int i = sorted.FirstInorder(); i != sorted.InvalidIndex(); i = sorted.NextInorder(i))
|
||||
{
|
||||
var = sorted[i];
|
||||
if (var->IsCommand())
|
||||
{
|
||||
PrintCommand((ConCommand*)var, bLogging, f);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintCvar((ConVar*)var, bLogging, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Show total and syntax help...
|
||||
if (partial && partial[0])
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "--------------\n%3i convars/concommands for [%s]\n", sorted.Count(), partial);
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "--------------\n%3i total convars/concommands\n", sorted.Count());
|
||||
}
|
||||
|
||||
if (bLogging)
|
||||
{
|
||||
FileSystem()->Close(f);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCvarUtilities::CvarHelp(const CCommand& args)
|
||||
{
|
||||
const char* search;
|
||||
ConCommandBase* var;
|
||||
|
||||
if (args.ArgC() != 2)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "Usage: help <cvarname>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get name of var to find
|
||||
search = args[1];
|
||||
|
||||
// Search for it
|
||||
var = g_pCVar->FindCommandBase(search);
|
||||
if (!var)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "Help: no cvar or command named %s\n", search);
|
||||
return;
|
||||
}
|
||||
|
||||
// Show info
|
||||
ConVar_PrintDescription(var);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCvarUtilities::CvarDifferences(const CCommand& args)
|
||||
{
|
||||
CCVarIteratorInternal* pFactory = g_pCVar->FactoryInternalIterator();
|
||||
pFactory->SetFirst();
|
||||
|
||||
while (pFactory->IsValid())
|
||||
{
|
||||
ConCommandBase* pCommandBase = pFactory->Get();
|
||||
|
||||
if (!pCommandBase->IsCommand() &&
|
||||
!pCommandBase->IsFlagSet(FCVAR_HIDDEN))
|
||||
{
|
||||
ConVar* pConVar = reinterpret_cast<ConVar*>(pCommandBase);
|
||||
|
||||
if (strcmp(pConVar->GetString(), "FCVAR_NEVER_AS_STRING") != NULL)
|
||||
{
|
||||
ConVar_PrintDescription(pConVar);
|
||||
}
|
||||
}
|
||||
pFactory->Next();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCvarUtilities::CvarFindFlags_f(const CCommand& args)
|
||||
{
|
||||
if (args.ArgC() < 2)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "Usage: findflags <string>\n");
|
||||
DevMsg(eDLL_T::ENGINE, "Available flags to search for: \n");
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(g_ConVarFlags); i++)
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, " - %s\n", g_ConVarFlags[i].desc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Get substring to find
|
||||
const char* search = args[1];
|
||||
ConCommandBase* var;
|
||||
|
||||
// Loop through vars and print out findings
|
||||
CCVarIteratorInternal* pFactory = g_pCVar->FactoryInternalIterator();
|
||||
pFactory->SetFirst();
|
||||
|
||||
while (pFactory->IsValid())
|
||||
{
|
||||
var = pFactory->Get();
|
||||
|
||||
if (!var->IsFlagSet(FCVAR_DEVELOPMENTONLY) || !var->IsFlagSet(FCVAR_HIDDEN))
|
||||
{
|
||||
for (int i = 0; i < ARRAYSIZE(g_ConVarFlags); i++)
|
||||
{
|
||||
if (var->IsFlagSet(g_ConVarFlags[i].bit))
|
||||
{
|
||||
if (V_stristr(g_ConVarFlags[i].desc, search))
|
||||
{
|
||||
ConVar_PrintDescription(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pFactory->Next();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CCvarUtilities::CvarFindFlagsCompletionCallback(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])
|
||||
{
|
||||
int flagC = ARRAYSIZE(g_ConVarFlags);
|
||||
char const* pcmd = "findflags ";
|
||||
int len = Q_strlen(partial);
|
||||
|
||||
if (len < Q_strlen(pcmd))
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < MIN(flagC, COMMAND_COMPLETION_MAXITEMS); i++)
|
||||
{
|
||||
Q_snprintf(commands[i], sizeof(commands[i]), "%s %s", pcmd, g_ConVarFlags[i].desc);
|
||||
Q_strlower(commands[i]);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
char const* pSub = partial + Q_strlen(pcmd);
|
||||
int nSubLen = Q_strlen(pSub);
|
||||
|
||||
int values = 0;
|
||||
for (int i = 0; i < flagC; ++i)
|
||||
{
|
||||
if (Q_strnicmp(g_ConVarFlags[i].desc, pSub, nSubLen))
|
||||
continue;
|
||||
|
||||
Q_snprintf(commands[values], sizeof(commands[values]), "%s %s", pcmd, g_ConVarFlags[i].desc);
|
||||
Q_strlower(commands[values]);
|
||||
++values;
|
||||
|
||||
if (values >= COMMAND_COMPLETION_MAXITEMS)
|
||||
break;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: registers input commands.
|
||||
// Input : *pszCommandName -
|
||||
|
@ -163,6 +163,54 @@ extern ConVar* pylon_showdebug;
|
||||
extern ConVar* rui_drawEnable;
|
||||
#endif // !DEDICATED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCvarUtilities
|
||||
{
|
||||
public:
|
||||
//bool IsCommand(const CCommand& args);
|
||||
|
||||
// Writes lines containing "set variable value" for all variables
|
||||
// with the archive flag set to true.
|
||||
//void WriteVariables(CUtlBuffer& buff, bool bAllVars);
|
||||
|
||||
// Returns the # of cvars with the server flag set.
|
||||
int CountVariablesWithFlags(int flags);
|
||||
|
||||
// Enable cvars marked with FCVAR_DEVELOPMENTONLY
|
||||
void EnableDevCvars();
|
||||
|
||||
// Lists cvars to console
|
||||
void CvarList(const CCommand& args);
|
||||
|
||||
// Prints help text for cvar
|
||||
void CvarHelp(const CCommand& args);
|
||||
|
||||
// Revert all cvar values
|
||||
//void CvarRevert(const CCommand& args);
|
||||
|
||||
// Revert all cvar values
|
||||
void CvarDifferences(const CCommand& args);
|
||||
|
||||
// Toggles a cvar on/off, or cycles through a set of values
|
||||
//void CvarToggle(const CCommand& args);
|
||||
|
||||
// Finds commands with a specified flag.
|
||||
void CvarFindFlags_f(const CCommand& args);
|
||||
|
||||
|
||||
int CvarFindFlagsCompletionCallback(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
||||
|
||||
private:
|
||||
// just like Cvar_set, but optimizes out the search
|
||||
//void SetDirect(ConVar* var, const char* value);
|
||||
|
||||
//bool IsValidToggleCommand(const char* cmd);
|
||||
};
|
||||
|
||||
extern CCvarUtilities* cv;
|
||||
|
||||
class CCVarIteratorInternal // Fully reversed table, just look at the virtual function table and rename the function.
|
||||
{
|
||||
public:
|
||||
@ -180,6 +228,7 @@ public:
|
||||
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);
|
||||
@ -189,6 +238,35 @@ public:
|
||||
|
||||
CCVarIteratorInternal* FactoryInternalIterator(void);
|
||||
unordered_map<string, ConCommandBase*> DumpToMap(void);
|
||||
|
||||
protected:
|
||||
friend class CCVarIteratorInternal;
|
||||
|
||||
enum ConVarSetType_t
|
||||
{
|
||||
CONVAR_SET_STRING = 0,
|
||||
CONVAR_SET_INT,
|
||||
CONVAR_SET_FLOAT,
|
||||
};
|
||||
|
||||
struct QueuedConVarSet_t
|
||||
{
|
||||
ConVar* m_pConVar;
|
||||
ConVarSetType_t m_nType;
|
||||
int m_nInt;
|
||||
float m_flFloat;
|
||||
//CUtlString m_String; // !TODO:
|
||||
};
|
||||
|
||||
private:
|
||||
void* m_pVFTable;
|
||||
CUtlVector< FnChangeCallback_t > m_GlobalChangeCallbacks;
|
||||
char pad0[22]; //!TODO:
|
||||
int m_nNextDLLIdentifier;
|
||||
ConCommandBase* m_pConCommandList;
|
||||
char m_CommandHash[208]; //!TODO:
|
||||
CUtlVector< QueuedConVarSet_t > m_QueuedConVarSets;
|
||||
bool m_bMaterialSystemThreadSetAllowed;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,5 +1,65 @@
|
||||
#include "core/stdafx.h"
|
||||
|
||||
FORCEINLINE unsigned char tolower_fast(unsigned char c)
|
||||
{
|
||||
if ((c >= 'A') && (c <= 'Z'))
|
||||
return c + ('a' - 'A');
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds a string in another string with a case insensitive test
|
||||
//-----------------------------------------------------------------------------
|
||||
char const* V_stristr(char const* pStr, char const* pSearch)
|
||||
{
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pStr));
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pSearch));
|
||||
|
||||
if (!pStr || !pSearch)
|
||||
return 0;
|
||||
|
||||
char const* pLetter = pStr;
|
||||
|
||||
// Check the entire string
|
||||
while (*pLetter != 0)
|
||||
{
|
||||
// Skip over non-matches
|
||||
if (tolower_fast((unsigned char)*pLetter) == tolower_fast((unsigned char)*pSearch))
|
||||
{
|
||||
// Check for match
|
||||
char const* pMatch = pLetter + 1;
|
||||
char const* pTest = pSearch + 1;
|
||||
while (*pTest != 0)
|
||||
{
|
||||
// We've run off the end; don't bother.
|
||||
if (*pMatch == 0)
|
||||
return 0;
|
||||
|
||||
if (tolower_fast((unsigned char)*pMatch) != tolower_fast((unsigned char)*pTest))
|
||||
break;
|
||||
|
||||
++pMatch;
|
||||
++pTest;
|
||||
}
|
||||
|
||||
// Found a match!
|
||||
if (*pTest == 0)
|
||||
return pLetter;
|
||||
}
|
||||
|
||||
++pLetter;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* V_stristr(char* pStr, char const* pSearch)
|
||||
{
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pStr));
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pSearch));
|
||||
|
||||
return (char*)V_stristr((char const*)pStr, pSearch);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts a UTF8 string into a unicode string
|
||||
|
@ -1,4 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#define V_snprintf snprintf
|
||||
#define V_strlower strlwr
|
||||
#define V_strlen strlen
|
||||
#define V_strncat strncat
|
||||
#define V_stricmp _stricmp
|
||||
#define V_strnicmp strnicmp
|
||||
#define V_strcmp strcmp
|
||||
|
||||
#define Q_snprintf V_snprintf
|
||||
#define Q_strlower V_strlower
|
||||
#define Q_strlen V_strlen
|
||||
#define Q_strncat V_strncat
|
||||
#define Q_stricmp V_stricmp
|
||||
#define Q_strnicmp V_strnicmp
|
||||
#define Q_strncasecmp V_strnicmp
|
||||
#define Q_strcasecmp V_stricmp
|
||||
#define Q_strcmp V_strcmp
|
||||
|
||||
char const* V_stristr(char const* pStr, char const* pSearch);
|
||||
|
||||
int V_UTF8ToUnicode(const char* pUTF8, wchar_t* pwchDest, int cubDestSizeInBytes);
|
||||
int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes);
|
@ -1053,3 +1053,29 @@ void BHit_f(const CCommand& args)
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CVList_f
|
||||
|
||||
List all ConCommandBases
|
||||
=====================
|
||||
*/
|
||||
void CVList_f(const CCommand& args)
|
||||
{
|
||||
cv->CvarList(args);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CVDiff_f
|
||||
|
||||
List all ConVar's
|
||||
who's values deviate
|
||||
from default value
|
||||
=====================
|
||||
*/
|
||||
void CVDiff_f(const CCommand& args)
|
||||
{
|
||||
cv->CvarDifferences(args);
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ void Sphere_f(const CCommand& args);
|
||||
void Capsule_f(const CCommand& args);
|
||||
#endif // !DEDICATED
|
||||
void BHit_f(const CCommand& args);
|
||||
void CVList_f(const CCommand& args);
|
||||
void CVDiff_f(const CCommand& args);
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VCallback : public IDetour
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user