1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 03:56:10 +08:00
Files
hl2sdk/public/icvar.h
2025-08-15 02:38:48 +03:00

298 lines
12 KiB
C++

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef ICVAR_H
#define ICVAR_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/IAppSystem.h"
#include "tier1/utlvector.h"
#include "tier1/characterset.h"
#include "utllinkedlist.h"
#include "utlhashtable.h"
#include "tier0/memalloc.h"
#include "convar.h"
#include <cstdint>
#include <functional>
// Shorthand helper to iterate registered convars
// Example usage:
// FOR_EACH_CONVAR( iter )
// {
// ConVarRefAbstract aref( iter );
// Msg( "%s = %d\n", aref.GetName(), aref.GetInt() );
//
// /* or use typed version, but make sure to check its validity after,
// since it would be invalid on type mismatch */
//
// CConVarRef<int> cref( iter );
// if(cref.IsValidRef())
// Msg( "%s = %d\n", cref.GetName(), cref.Get() );
// }
#define FOR_EACH_CONVAR( iter ) for(ConVarRef iter = g_pCVar->FindFirstConVar(); iter.IsValidRef(); iter = g_pCVar->FindNextConVar( iter ))
// Shorthand helper to iterate registered concommands
#define FOR_EACH_CONCOMMAND( iter ) for(ConCommandRef iter = icvar->FindFirstConCommand(); iter.IsValidRef(); iter = icvar->FindNextConCommand( iter ))
typedef uint8 *ConVarUserInfoSet_t;
struct ConVarSnapshot_t;
class KeyValues;
typedef std::function<void( FnGenericChangeCallbackProvider_t, FnGenericChangeCallback_t )> FnCvarCallbacksReader_t;
//-----------------------------------------------------------------------------
// Called when a ConVar changes value
//-----------------------------------------------------------------------------
typedef void(*FnChangeCallbackGlobal_t)(ConVarRefAbstract* ref, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue, void *__unk01);
//-----------------------------------------------------------------------------
// ConVar & ConCommand creation listener callbacks
//-----------------------------------------------------------------------------
class IConVarListener
{
public:
virtual void OnConVarCreated( ConVarRefAbstract *pNewCvar ) {};
virtual void OnConCommandCreated( ConCommand *pNewCommand ) {};
};
//-----------------------------------------------------------------------------
// Purpose: DLL interface to ConVars/ConCommands
//-----------------------------------------------------------------------------
abstract_class ICvar : public IAppSystem
{
public:
// allow_defensive - Allows finding convars with FCVAR_DEFENSIVE flag
virtual ConVarRef FindConVar( const char *name, bool allow_defensive = false ) = 0;
virtual ConVarRef FindFirstConVar() = 0;
virtual ConVarRef FindNextConVar( ConVarRef prev ) = 0;
virtual void CallChangeCallback( ConVarRef cvar, const CSplitScreenSlot nSlot, const CVValue_t* pNewValue, const CVValue_t* pOldValue, void *__unk01 = nullptr ) = 0;
// Would call cb for every change callback defined for this cvar
virtual void IterateConVarCallbacks( ConVarRef cvar, FnCvarCallbacksReader_t cb ) = 0;
// If returns false value shouldn't be modified
virtual bool CallFilterCallback( ConVarRef cvar, const CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue, void *__unk01 = nullptr ) = 0;
// allow_defensive - Allows finding commands with FCVAR_DEFENSIVE flag
virtual ConCommandRef FindConCommand( const char *name, bool allow_defensive = false ) = 0;
virtual ConCommandRef FindFirstConCommand() = 0;
virtual ConCommandRef FindNextConCommand( ConCommandRef prev ) = 0;
virtual void DispatchConCommand( ConCommandRef cmd, const CCommandContext &ctx, const CCommand &args ) = 0;
// Install a global change callback (to be called when any convar changes)
virtual void InstallGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0;
virtual void RemoveGlobalChangeCallback( FnChangeCallbackGlobal_t callback ) = 0;
virtual void CallGlobalChangeCallbacks( ConVarRefAbstract* ref, CSplitScreenSlot nSlot, const char* newValue, const char* oldValue, void *__unk01 = nullptr ) = 0;
// Reverts cvars to default values which contain a specific flag,
// cvars with a flag FCVAR_COMMANDLINE_ENFORCED would be skipped
virtual void ResetConVarsToDefaultValuesByFlag( uint64 nFlag ) = 0;
virtual void SetMaxSplitScreenSlots( int nSlots ) = 0;
virtual int GetMaxSplitScreenSlots() const = 0;
virtual void RegisterCreationListeners( IConVarListener *callbacks ) = 0;
virtual void RemoveCreationListeners( IConVarListener *callbacks ) = 0;
virtual void unk001() = 0;
// Reverts cvars to default values which match pszPrefix string,
// ignores FCVAR_COMMANDLINE_ENFORCED
virtual void ResetConVarsToDefaultValuesByName( const char *pszPrefix ) = 0;
virtual ConVarSnapshot_t *TakeConVarSnapshot( void ) = 0;
virtual void ResetConVarsToSnapshot( ConVarSnapshot_t *pSnapshot ) = 0;
virtual void DestroyConVarSnapshot( ConVarSnapshot_t *pSnapshot ) = 0;
virtual characterset_t *GetCharacterSet( void ) = 0;
virtual void SetConVarsFromGameInfo( KeyValues *pKV ) = 0;
// Removes FCVAR_DEVELOPMENTONLY | FCVAR_DEFENSIVE from all cvars and concommands
// that have FCVAR_DEFENSIVE set
virtual void StripDevelopmentFlags() = 0;
// Returns total bytesize needed to store all the FCVAR_USERINFO cvar values
virtual int GetTotalUserInfoCvarsByteSize() = 0;
// Copies default values of all cvars which have FCVAR_USERINFO flag to the buffer in a byte range from->to
// if copy_or_cleanup is true, if false would cleanup the buffer
virtual void CopyUserInfoCvarDefaults( ConVarUserInfoSet_t buffer, int from, int to, bool copy_or_cleanup ) = 0;
// Register, unregister vars
virtual void RegisterConVar( const ConVarCreation_t& setup, uint64 nAdditionalFlags, ConVarRef* pCvarRef, ConVarData** pCvarData ) = 0;
// Unregisters convar change callback, but leaves the convar in the lists,
// so all ConVarRefs would still be valid as well as searching for it.
// Expects ref to have registered index to be set (is set on convar creation)
virtual void UnregisterConVarCallbacks( ConVarRef cvar ) = 0;
// Prevents default value initialisation on convars if state equals true and queues them instead,
// unlocks and initialises queued convars to default values if state is false
virtual void LockConVarValueInitialisation( bool state ) = 0;
// Returns convar data or nullptr if not found
virtual ConVarData* GetConVarData( ConVarRef cvar ) = 0;
// Register, unregister commands
virtual ConCommandRef RegisterConCommand( const ConCommandCreation_t& setup, uint64 nAdditionalFlags = 0 ) = 0;
// Unregisters concommand callbacks, but leaves the command in the lists,
// so all ConCommandRefs would still be valid as well as searching for it.
// Expects ref to have registered index to be set (is set on command creation)
virtual void UnregisterConCommandCallbacks( ConCommandRef cmd ) = 0;
// Returns command info or empty <unknown> command struct if not found, never nullptr
virtual ConCommandData* GetConCommandData( ConCommandRef cmd ) = 0;
// Queues up value (creates a copy of it) to be set when convar is ready to be edited
virtual void QueueThreadSetValue( ConVarRefAbstract* ref, CSplitScreenSlot nSlot, void* __unk01, CVValue_t* value ) = 0;
};
#include "memdbgon.h"
// AMNOTE: CCvar definition is mostly for reference and is reverse engineered
// You shouldn't be using this to directly register cvars/concommands, use its interface instead when possible
class CCvar : public ICvar
{
public:
static const int kMemoryBufferChunkMaxSize = 8192;
static const int kStringBufferChunkMaxSize = 2048;
// Allocates memory in its internal buffer, can't be freed
// (other than freeing internal buffers completely), so is leaky and thus use cautiously
// AMNOTE: Mostly used for allocating CVValue_t and ConVarData/ConCommandData objects
void *AllocateMemory( int size )
{
int aligned_size = ALIGN_VALUE( size, 8 );
if(aligned_size + m_CurrentMemoryBufferSize > kMemoryBufferChunkMaxSize)
{
m_CurrentMemoryBufferSize = 0;
*m_MemoryBuffer.AddToTailGetPtr() = (uint8 *)malloc( kMemoryBufferChunkMaxSize );
}
int offs = m_CurrentMemoryBufferSize;
m_CurrentMemoryBufferSize += aligned_size;
return &m_MemoryBuffer[m_MemoryBuffer.Count() - 1][offs];
}
// Allocates memory in its internal string buffer, can't be freed
// (other than freeing internal buffers completely), so is leaky and thus use cautiously
// AMNOTE: Mostly used for allocating cvar/concommand names
const char *AllocateString( const char *string )
{
if(!string || !string[0])
return "";
int strlen = V_strlen( string ) + 1;
if(strlen + m_CurrentStringsBufferSize > kStringBufferChunkMaxSize)
{
m_CurrentStringsBufferSize = 0;
*m_StringsBuffer.AddToTailGetPtr() = (char *)malloc( kStringBufferChunkMaxSize );
}
int offs = m_CurrentStringsBufferSize;
m_CurrentStringsBufferSize += strlen;
char *base = &m_StringsBuffer[m_StringsBuffer.Count() - 1][offs];
V_memmove( base, string, strlen );
return base;
}
struct ConVarChangeCallbackData_t
{
FnGenericChangeCallbackProvider_t m_pProviderCallBack;
FnGenericChangeCallback_t m_pCallback;
// Register index of cvar which change cb comes from
int m_ConVarIndex;
};
struct ConVarFilterCallbackData_t
{
FnGenericFilterCallbackProvider_t m_pProviderCallBack;
FnGenericFilterCallback_t m_pCallback;
// Register index of cvar which change cb comes from
int m_ConVarIndex;
};
struct ConCommandCallbackInfoNode_t
{
ConCommandCallbackInfo_t m_CB;
// Register index of concommand which completion cb comes from
int m_ConCmdIndex;
// Index in a linkedlist of callbackinfos
uint16 m_CallbackInfoIndex;
};
struct QueuedConVarSet_t
{
ConVarRefAbstract *m_ConVar;
CSplitScreenSlot m_Slot;
void *m_unk001;
CVValue_t *m_Value;
};
CUtlVector<char *> m_StringsBuffer;
CUtlVector<uint8 *> m_MemoryBuffer;
int m_CurrentStringsBufferSize;
int m_CurrentMemoryBufferSize;
CUtlLinkedList<ConVarData *> m_ConVarList;
CUtlHashtable<CUtlStringToken, uint16> m_ConVarHashes;
CUtlLinkedList<ConVarChangeCallbackData_t, unsigned short, true> m_ConVarChangeCBList;
CUtlLinkedList<ConVarFilterCallbackData_t, unsigned short, true> m_ConVarFilterCBList;
int m_ConVarCount;
CUtlVector<IConVarListener *> m_CvarCreationListeners;
CUtlVector<FnChangeCallbackGlobal_t> m_GlobalChangeCBList;
CUtlLinkedList<ConCommandData> m_ConCommandList;
CUtlHashtable<CUtlStringToken, uint16> m_ConCommandHashes;
CUtlLinkedList<ConCommandCallbackInfoNode_t, unsigned short, true> m_CallbackInfoList;
int m_ConCommandCount;
int m_SplitScreenSlots;
CThreadMutex m_Mutex;
characterset_t m_CharacterSet;
KeyValues *m_GameInfoKV;
uint8 m_CvarDefaultValues[EConVarType_MAX][128];
CUtlVector<QueuedConVarSet_t> m_SetValueQueue;
CUtlVector<ConVarRef> m_SetToDefaultValueQueue;
bool m_LockDefaultValueInit;
int m_UserInfoCvarsTotalByteSize;
CConCommandMemberAccessor<CCvar> m_FindCmd;
CConCommandMemberAccessor<CCvar> m_DumpChannelsCmd;
CConCommandMemberAccessor<CCvar> m_LogLevelCmd;
CConCommandMemberAccessor<CCvar> m_LogVerbosityCmd;
CConCommandMemberAccessor<CCvar> m_LogColorCmd;
CConCommandMemberAccessor<CCvar> m_LogFlagsCmd;
CConCommandMemberAccessor<CCvar> m_DifferencesCmd;
CConCommandMemberAccessor<CCvar> m_CvarListCmd;
CConCommandMemberAccessor<CCvar> m_HelpCmd;
CConCommandMemberAccessor<CCvar> m_FindFlagsCmd;
};
#include "memdbgoff.h"
//-----------------------------------------------------------------------------
// These global names are defined by tier1.h, duplicated here so you
// don't have to include tier1.h
//-----------------------------------------------------------------------------
// These are marked DLL_EXPORT for Linux.
DECLARE_TIER1_INTERFACE( ICvar, cvar );
DECLARE_TIER1_INTERFACE( ICvar, g_pCVar );
#endif // ICVAR_H