diff --git a/public/icvar.h b/public/icvar.h index c70c4f49..5fff2e60 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -18,6 +18,7 @@ #include "tier0/memalloc.h" #include "convar.h" #include +#include // Shorthand helper to iterate registered convars // Example usage: @@ -42,10 +43,12 @@ struct ConVarSnapshot_t; class KeyValues; +typedef std::function FnCvarCallbacksReader_t; + //----------------------------------------------------------------------------- // Called when a ConVar changes value //----------------------------------------------------------------------------- -typedef void(*FnChangeCallbackGlobal_t)(ConVarRefAbstract* ref, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue); +typedef void(*FnChangeCallbackGlobal_t)(ConVarRefAbstract* ref, CSplitScreenSlot nSlot, const char *pNewValue, const char *pOldValue, void *__unk01); //----------------------------------------------------------------------------- // ConVar & ConCommand creation listener callbacks @@ -67,7 +70,10 @@ public: 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 ) = 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; // allow_defensive - Allows finding commands with FCVAR_DEFENSIVE flag virtual ConCommandRef FindConCommand( const char *name, bool allow_defensive = false ) = 0; @@ -78,7 +84,7 @@ public: // 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 ) = 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 @@ -106,6 +112,12 @@ public: // 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( uint8* 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; @@ -126,7 +138,7 @@ public: 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, CVValue_t* value ) = 0; + virtual void QueueThreadSetValue( ConVarRefAbstract* ref, CSplitScreenSlot nSlot, void* __unk01, CVValue_t* value ) = 0; }; #include "memdbgon.h" @@ -185,6 +197,7 @@ public: struct CConVarChangeCallbackNode_t { + FnGenericChangeCallbackProvider_t m_pProviderCallBack; FnGenericChangeCallback_t m_pCallback; // Register index of cvar which change cb comes from @@ -205,6 +218,7 @@ public: { ConVarRefAbstract *m_ConVar; CSplitScreenSlot m_Slot; + void *m_unk001; CVValue_t *m_Value; }; @@ -236,6 +250,11 @@ public: CUtlVector m_SetValueQueue; + CUtlVector m_SetToDefaultValueQueue; + bool m_LockDefaultValueInit; + + int m_UserInfoCvarsTotalByteSize; + CConCommandMemberAccessor m_FindCmd; CConCommandMemberAccessor m_DumpChannelsCmd; CConCommandMemberAccessor m_LogLevelCmd; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index a52caf95..68530004 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -607,7 +607,16 @@ private: void Destroy( ); }; -using FnGenericChangeCallback_t = void(*)(ConVarRefAbstract* ref, CSplitScreenSlot nSlot, const CVValue_t* pNewValue, const CVValue_t* pOldValue); +template +class CConVar; + +template +using FnTypedChangeCallback_t = void (*)(CConVar *cvar, CSplitScreenSlot nSlot, const T *pNewValue, const T *pOldValue); +template +using FnTypedChangeCallbackProvider_t = void(*)(CConVar *cvar, CSplitScreenSlot slot, const T *pNewValue, const T *pOldValue, void *__unk01, FnTypedChangeCallback_t cb); + +using FnGenericChangeCallback_t = void(*)(ConVarRefAbstract *ref, CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue); +using FnGenericChangeCallbackProvider_t = void(*)(ConVarRefAbstract *ref, CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue, void *__unk01, FnGenericChangeCallback_t cb); struct ConVarValueInfo_t { @@ -644,6 +653,19 @@ struct ConVarValueInfo_t *reinterpret_cast(m_maxValue) = max; } + template + void SetCallback( FnTypedChangeCallback_t cb ) + { + if(cb) + { + m_fnProviderCallBack = []( ConVarRefAbstract *ref, CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue, void *__unk01, FnGenericChangeCallback_t cb ) { + reinterpret_cast>(cb)(reinterpret_cast *>(ref), nSlot, reinterpret_cast(pNewValue), reinterpret_cast(pOldValue)); + }; + + m_fnCallBack = reinterpret_cast(cb); + } + } + int32 m_Version; bool m_bHasDefault; @@ -858,6 +880,7 @@ public: int GetGameInfoFlags() const { return m_GameInfoFlags; } int GetCallbackIndex() const { return m_iCallbackIndex; } + int GetUserInfoByteIndex() const { return m_UserInfoByteIndex; } int GetMaxSplitScreenSlots() const; @@ -945,10 +968,11 @@ private: unsigned int m_iCallbackIndex; int m_GameInfoFlags; + int m_UserInfoByteIndex; // At convar registration this is trimmed to better match convar type being used // or if it was initialized as EConVarType_Invalid it would be of this size - uint8 m_Values[sizeof( CVValue_t ) * MAX_SPLITSCREEN_CLIENTS]; + alignas( CVValue_t ) uint8 m_Values[sizeof( CVValue_t ) * MAX_SPLITSCREEN_CLIENTS]; }; static ConVarData *GetInvalidConVarData( EConVarType type ) diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 99004f74..afbfce07 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -590,7 +590,7 @@ void ConVarRefAbstract::QueueSetValueInternal( CSplitScreenSlot slot, CVValue_t TypeTraits()->Clamp( value, m_ConVarData->MinValue(), m_ConVarData->MaxValue() ); if(!m_ConVarData->IsEqual( slot, value )) - g_pCVar->QueueThreadSetValue( this, slot, value ); + g_pCVar->QueueThreadSetValue( this, slot, nullptr, value ); } void ConVarRefAbstract::SetValueInternal( CSplitScreenSlot slot, CVValue_t *value )