From 66ff5a54d017ac5547ea419362c3f427146897e3 Mon Sep 17 00:00:00 2001 From: samyyc Date: Sun, 9 Nov 2025 00:36:05 +0800 Subject: [PATCH 1/4] feat(managed): Refactor cvar --- .../SwiftlyS2.Core/Modules/Convars/ConVar.cs | 156 ++++++++++++++++-- .../SwiftlyS2.Core/Services/TestService.cs | 29 +++- .../SwiftlyS2.Generated/Natives/Convars.cs | 91 ++++++++-- .../Modules/Convars/IConVar.cs | 42 +++-- .../Modules/Convars/IConVarService.cs | 2 +- .../Modules/Engine/ITraceManager.cs | 4 +- .../Natives/Structs/CUtlString.cs | 2 +- managed/src/TestPlugin/TestPlugin.cs | 8 +- natives/engine/convars.native | 12 +- src/api/engine/convars/convars.h | 3 + src/engine/convars/convars.cpp | 13 ++ src/engine/convars/convars.h | 4 + src/scripting/engine/convars.cpp | 76 ++++++--- vendor/s2sdk | 2 +- 14 files changed, 360 insertions(+), 84 deletions(-) diff --git a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs index c88a7c18d..7e1d79320 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs @@ -3,6 +3,7 @@ using SwiftlyS2.Shared.Natives; using SwiftlyS2.Core.Extensions; using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; namespace SwiftlyS2.Core.Convars; @@ -13,35 +14,69 @@ internal class ConVar : IConVar{ private Dictionary _callbacks = new(); private object _lock = new(); - public string Name { get; set; } + private nint _minValuePtrPtr => NativeConvars.GetMinValuePtrPtr(Name); + private nint _maxValuePtrPtr => NativeConvars.GetMaxValuePtrPtr(Name); - internal ConVar(string name) { - Name = name; - } + public EConVarType Type => (EConVarType)NativeConvars.GetConvarType(Name); - public void AddFlags(ConvarFlags flags) - { - NativeConvars.AddFlags(Name, (ulong)flags); + private bool IsValidType => Type > EConVarType.EConVarType_Invalid && Type < EConVarType.EConVarType_MAX; + + // im not sure + private bool IsMinMaxType => IsValidType && Type != EConVarType.EConVarType_String && Type != EConVarType.EConVarType_Color; + + public T MinValue { + get => GetMinValue(); + set => SetMinValue(value); + } + public T MaxValue { + get => GetMaxValue(); + set => SetMaxValue(value); } - public void RemoveFlags(ConvarFlags flags) - { - NativeConvars.RemoveFlags(Name, (ulong)flags); + public T DefaultValue { + get => GetDefaultValue(); + set => SetDefaultValue(value); } - public void ClearFlags() - { - NativeConvars.ClearFlags(Name); + public ConvarFlags Flags { + get => (ConvarFlags)NativeConvars.GetFlags(Name); + set => NativeConvars.SetFlags(Name, (ulong)value); } - public ConvarFlags GetFlags() - { - return (ConvarFlags)NativeConvars.GetFlags(Name); + public bool HasDefaultValue => NativeConvars.HasDefaultValue(Name); + + public bool HasMinValue => _minValuePtrPtr.Read() != 0; + public bool HasMaxValue => _maxValuePtrPtr.Read() != 0; + + public string Name { get; set; } + + internal ConVar(string name) { + Name = name; + + ValidateType(); } - public bool HasFlags(ConvarFlags flags) + public void ValidateType() { - return (GetFlags() & flags) == flags; + if ( + (typeof(T) == typeof(bool) && Type != EConVarType.EConVarType_Bool) || + (typeof(T) == typeof(short) && Type != EConVarType.EConVarType_Int16) || + (typeof(T) == typeof(ushort) && Type != EConVarType.EConVarType_UInt16) || + (typeof(T) == typeof(int) && Type != EConVarType.EConVarType_Int32) || + (typeof(T) == typeof(uint) && Type != EConVarType.EConVarType_UInt32) || + (typeof(T) == typeof(float) && Type != EConVarType.EConVarType_Float32) || + (typeof(T) == typeof(long) && Type != EConVarType.EConVarType_Int64) || + (typeof(T) == typeof(ulong) && Type != EConVarType.EConVarType_UInt64) || + (typeof(T) == typeof(double) && Type != EConVarType.EConVarType_Float64) || + (typeof(T) == typeof(Color) && Type != EConVarType.EConVarType_Color) || + (typeof(T) == typeof(QAngle) && Type != EConVarType.EConVarType_Qangle) || + (typeof(T) == typeof(Vector) && Type != EConVarType.EConVarType_Vector3) || + (typeof(T) == typeof(Vector2D) && Type != EConVarType.EConVarType_Vector2) || + (typeof(T) == typeof(Vector4D) && Type != EConVarType.EConVarType_Vector4) || + (typeof(T) == typeof(string) && Type != EConVarType.EConVarType_String) + ) { + throw new Exception($"Type mismatch for convar {Name}. The real type is {Type}."); + } } public T Value { @@ -327,4 +362,89 @@ public void QueryClient(int clientId, Action callback) NativeConvars.QueryClientConvar(clientId, Name); } + public T GetMinValue() + { + if (!IsMinMaxType) { + throw new Exception($"Convar {Name} is not a min/max type."); + } + if (!HasMinValue) { + throw new Exception($"Convar {Name} doesn't have a min value."); + } + unsafe { + return **(T**)_minValuePtrPtr; + } + } + + public T GetMaxValue() + { + if (!IsMinMaxType) { + throw new Exception($"Convar {Name} is not a min/max type."); + } + if (!HasMaxValue) { + throw new Exception($"Convar {Name} doesn't have a max value."); + } + unsafe { + return **(T**)_maxValuePtrPtr; + } + } + public void SetMinValue(T minValue) + { + if (!IsMinMaxType) { + throw new Exception($"Convar {Name} is not a min/max type."); + } + unsafe + { + if (_minValuePtrPtr.Read() == nint.Zero) { + _minValuePtrPtr.Write(NativeAllocator.Alloc(16)); + } + **(T**)_minValuePtrPtr = minValue; + } + } + + public void SetMaxValue(T maxValue) + { + if (!IsMinMaxType) { + throw new Exception($"Convar {Name} is not a min/max type."); + } + unsafe + { + if (_maxValuePtrPtr.Read() == nint.Zero) + { + _maxValuePtrPtr.Write(NativeAllocator.Alloc(16)); + } + **(T**)_maxValuePtrPtr = maxValue; + } + } + + public T GetDefaultValue() + { + unsafe { + var ptr = NativeConvars.GetDefaultValuePtr(Name); + if (ptr == nint.Zero) { + throw new Exception($"Convar {Name} doesn't have a default value."); + } + if (Type != EConVarType.EConVarType_String) { + return *(T*)ptr; + } + else { + return (T)(object)(*(CUtlString*)ptr).Value; + } + } + } + + public void SetDefaultValue(T defaultValue) + { + unsafe { + var ptr = NativeConvars.GetDefaultValuePtr(Name); + if (ptr == nint.Zero) { + throw new Exception($"Convar {Name} doesn't have a default value."); + } + if (Type != EConVarType.EConVarType_String) { + *(T*)NativeConvars.GetDefaultValuePtr(Name) = defaultValue; + } + else { + NativeConvars.GetDefaultValuePtr(Name).Write(StringPool.Allocate((string)(object)defaultValue)); + } + } + } } diff --git a/managed/src/SwiftlyS2.Core/Services/TestService.cs b/managed/src/SwiftlyS2.Core/Services/TestService.cs index bb3fc2dcb..2c0869b62 100644 --- a/managed/src/SwiftlyS2.Core/Services/TestService.cs +++ b/managed/src/SwiftlyS2.Core/Services/TestService.cs @@ -37,6 +37,16 @@ ISwiftlyCore core _Core = core; _Logger = logger; + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + _Logger.LogWarning("TestService created"); + Test(); } @@ -44,9 +54,22 @@ ISwiftlyCore core public void Test() { _Core.Command.RegisterCommand("rrr", (context) => { - _Core.Engine.ExecuteCommandWithBuffer("echo 1", (buffer) => { - Console.WriteLine(buffer); - }); + + var a = _Core.ConVar.Create("test_convar", "Test convar", 123); + + Console.WriteLine(a.Flags.HasFlag(ConvarFlags.DEVELOPMENT_ONLY)); + + // setting this to DEVELOPMENT_ONLY will cause a crash later + // because if its development only, the ConVarRefAbstract will not be able to find the ConvarData + // eventually return a nullptr in GetConvarData + a.Flags |= ConvarFlags.REPLICATED; + + Console.WriteLine(a.Flags.HasFlag(ConvarFlags.REPLICATED)); + Console.WriteLine(a.Flags.HasFlag(ConvarFlags.CHEAT)); + + Console.WriteLine(a.DefaultValue); + a.DefaultValue = 234; + Console.WriteLine(a.DefaultValue); }); // _Core.Event.OnItemServicesCanAcquireHook += (@event) => { // Console.WriteLine(@event.EconItemView.ItemDefinitionIndex); diff --git a/managed/src/SwiftlyS2.Generated/Natives/Convars.cs b/managed/src/SwiftlyS2.Generated/Natives/Convars.cs index 491dd2f7a..ecff01781 100644 --- a/managed/src/SwiftlyS2.Generated/Natives/Convars.cs +++ b/managed/src/SwiftlyS2.Generated/Natives/Convars.cs @@ -1135,60 +1135,127 @@ public unsafe static void SetClientConvarValueString(int playerid, string cvarNa } } - private unsafe static delegate* unmanaged _AddFlags; + private unsafe static delegate* unmanaged _GetFlags; - public unsafe static void AddFlags(string cvarName, ulong flags) { + public unsafe static ulong GetFlags(string cvarName) { var pool = ArrayPool.Shared; var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); var cvarNameBuffer = pool.Rent(cvarNameLength + 1); Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); cvarNameBuffer[cvarNameLength] = 0; fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _AddFlags(cvarNameBufferPtr, flags); + var ret = _GetFlags(cvarNameBufferPtr); pool.Return(cvarNameBuffer); + return ret; } } - private unsafe static delegate* unmanaged _RemoveFlags; + private unsafe static delegate* unmanaged _SetFlags; - public unsafe static void RemoveFlags(string cvarName, ulong flags) { + public unsafe static void SetFlags(string cvarName, ulong flags) { var pool = ArrayPool.Shared; var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); var cvarNameBuffer = pool.Rent(cvarNameLength + 1); Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); cvarNameBuffer[cvarNameLength] = 0; fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _RemoveFlags(cvarNameBufferPtr, flags); + _SetFlags(cvarNameBufferPtr, flags); pool.Return(cvarNameBuffer); } } - private unsafe static delegate* unmanaged _ClearFlags; + private unsafe static delegate* unmanaged _GetMinValuePtrPtr; - public unsafe static void ClearFlags(string cvarName) { + public unsafe static nint GetMinValuePtrPtr(string cvarName) { var pool = ArrayPool.Shared; var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); var cvarNameBuffer = pool.Rent(cvarNameLength + 1); Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); cvarNameBuffer[cvarNameLength] = 0; fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _ClearFlags(cvarNameBufferPtr); + var ret = _GetMinValuePtrPtr(cvarNameBufferPtr); pool.Return(cvarNameBuffer); + return ret; } } - private unsafe static delegate* unmanaged _GetFlags; + private unsafe static delegate* unmanaged _GetMaxValuePtrPtr; - public unsafe static ulong GetFlags(string cvarName) { + public unsafe static nint GetMaxValuePtrPtr(string cvarName) { var pool = ArrayPool.Shared; var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); var cvarNameBuffer = pool.Rent(cvarNameLength + 1); Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); cvarNameBuffer[cvarNameLength] = 0; fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetFlags(cvarNameBufferPtr); + var ret = _GetMaxValuePtrPtr(cvarNameBufferPtr); pool.Return(cvarNameBuffer); return ret; } } + + private unsafe static delegate* unmanaged _HasDefaultValue; + + public unsafe static bool HasDefaultValue(string cvarName) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + var ret = _HasDefaultValue(cvarNameBufferPtr); + pool.Return(cvarNameBuffer); + return ret == 1; + } + } + + private unsafe static delegate* unmanaged _GetDefaultValuePtr; + + public unsafe static nint GetDefaultValuePtr(string cvarName) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + var ret = _GetDefaultValuePtr(cvarNameBufferPtr); + pool.Return(cvarNameBuffer); + return ret; + } + } + + private unsafe static delegate* unmanaged _SetDefaultValue; + + public unsafe static void SetDefaultValue(string cvarName, nint defaultValue) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + _SetDefaultValue(cvarNameBufferPtr, defaultValue); + pool.Return(cvarNameBuffer); + } + } + + private unsafe static delegate* unmanaged _SetDefaultValueString; + + public unsafe static void SetDefaultValueString(string cvarName, string defaultValue) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + var defaultValueLength = Encoding.UTF8.GetByteCount(defaultValue); + var defaultValueBuffer = pool.Rent(defaultValueLength + 1); + Encoding.UTF8.GetBytes(defaultValue, defaultValueBuffer); + defaultValueBuffer[defaultValueLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + fixed (byte* defaultValueBufferPtr = defaultValueBuffer) { + _SetDefaultValueString(cvarNameBufferPtr, defaultValueBufferPtr); + pool.Return(cvarNameBuffer); + pool.Return(defaultValueBuffer); + } + } + } } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs index c959f889f..0c8b2b9b5 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs @@ -11,34 +11,44 @@ public interface IConVar { T Value { get; set; } /// - /// Add flags to the convar. + /// The max value of the convar. + /// + /// Thrown when the convar is not a min/max type or doesn't have a max value. /// - /// flags. - void AddFlags(ConvarFlags flags); + T MaxValue { get; set; } /// - /// Remove flags from the convar. + /// The min value of the convar. + /// + /// Thrown when the convar is not a min/max type or doesn't have a min value. /// - /// flags. - void RemoveFlags(ConvarFlags flags); + T MinValue { get; set; } /// - /// Clear all flags from the convar. + /// The default value of the convar. /// - void ClearFlags(); + T DefaultValue { get; set; } /// - /// Get the flags of the convar. + /// Whether the convar has a default value. /// - /// The flags of the convar. - ConvarFlags GetFlags(); + bool HasDefaultValue { get; } /// - /// Check if the convar has the given flags. + /// Whether the convar has a min value. /// - /// flags. - /// True if the convar has all the given flags, false otherwise. - bool HasFlags(ConvarFlags flags); + bool HasMinValue { get; } + + /// + /// Whether the convar has a max value. + /// + bool HasMaxValue { get; } + + /// + /// The flags of the convar. + /// + ConvarFlags Flags { get; set; } + /// /// Internally set the value of the convar. @@ -57,6 +67,6 @@ public interface IConVar { /// Query the value of the convar from specified client. /// /// - /// The action to execute with the value. + /// The action to execute with the value. void QueryClient(int clientId, Action callback); } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs index 670b34c66..bd1fa0ba2 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs @@ -33,5 +33,5 @@ public interface IConVarService { /// The min value of the convar. /// The max value of the convar. /// The created convar. - IConVar Create(string name, string helpMessage, T defaultValue, T? minValue = null, T? maxValue = null, ConvarFlags flags = ConvarFlags.NONE) where T: unmanaged; + IConVar Create(string name, string helpMessage, T defaultValue, T? minValue, T? maxValue, ConvarFlags flags = ConvarFlags.NONE) where T: unmanaged; } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Modules/Engine/ITraceManager.cs b/managed/src/SwiftlyS2.Shared/Modules/Engine/ITraceManager.cs index 06dd9adc8..ddb21e25f 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Engine/ITraceManager.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Engine/ITraceManager.cs @@ -15,7 +15,7 @@ public interface ITraceManager /// The trace filter used to determine which entities or surfaces are considered during the trace operation. /// A reference to a CGameTrace object that receives the results of the trace, including collision information and /// hit details. - void TracePlayerBBox(Vector start, Vector end, BBox_t bounds, CTraceFilter filter, ref CGameTrace trace); + public void TracePlayerBBox(Vector start, Vector end, BBox_t bounds, CTraceFilter filter, ref CGameTrace trace); /// /// Performs a trace operation from the specified start point to the end point using the given ray and filter, and /// populates the trace result with collision information. @@ -26,5 +26,5 @@ public interface ITraceManager /// The filter that determines which entities or surfaces are considered during the trace. /// A reference to a CGameTrace structure that receives the results of the trace, including hit information and /// surface details. - void TraceShape(Vector start, Vector end, Ray_t ray, CTraceFilter filter, ref CGameTrace trace); + public void TraceShape(Vector start, Vector end, Ray_t ray, CTraceFilter filter, ref CGameTrace trace); } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs b/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs index b27774fda..2c51e8787 100644 --- a/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs +++ b/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs @@ -20,5 +20,5 @@ public string Value { } public static implicit operator string(CUtlString str) => str.Value; - public static implicit operator CUtlString(string str) => new CUtlString { _ptr = StringPool.Allocate(str) }; + public static implicit operator CUtlString(string str) => new() { _ptr = StringPool.Allocate(str) }; } \ No newline at end of file diff --git a/managed/src/TestPlugin/TestPlugin.cs b/managed/src/TestPlugin/TestPlugin.cs index 21eebf47f..6398c2ec7 100644 --- a/managed/src/TestPlugin/TestPlugin.cs +++ b/managed/src/TestPlugin/TestPlugin.cs @@ -535,18 +535,18 @@ public HookResult TestServerNetMessageHandler( CCSUsrMsg_SendPlayerItemDrops msg return HookResult.Continue; } - private Callback _authTicketResponse; + private Callback _authTicketResponse; [EventListener] public void OnSteamAPIActivated() { Console.WriteLine("TestPlugin OnSteamAPIActivated"); - _authTicketResponse = Callback.Create(AuthResponse); + _authTicketResponse = Callback.Create(AuthResponse); } - public void AuthResponse( ValidateAuthTicketResponse_t param ) + public void AuthResponse( GCMessageAvailable_t param ) { - Console.WriteLine($"AuthResponse {param.m_eAuthSessionResponse} -> {param.m_SteamID.m_SteamID}"); + Console.WriteLine($"AuthResponse {param.m_nMessageSize}"); } [Command("getip")] diff --git a/natives/engine/convars.native b/natives/engine/convars.native index 4d6912017..eddd1b092 100644 --- a/natives/engine/convars.native +++ b/natives/engine/convars.native @@ -73,7 +73,11 @@ void SetClientConvarValueVector = int32 playerid, string cvarName, vector defaul void SetClientConvarValueVector4D = int32 playerid, string cvarName, vector4 defaultValue void SetClientConvarValueQAngle = int32 playerid, string cvarName, qangle defaultValue void SetClientConvarValueString = int32 playerid, string cvarName, string defaultValue -void AddFlags = string cvarName, uint64 flags -void RemoveFlags = string cvarName, uint64 flags -void ClearFlags = string cvarName -uint64 GetFlags = string cvarName \ No newline at end of file +uint64 GetFlags = string cvarName +void SetFlags = string cvarName, uint64 flags +ptr GetMinValuePtrPtr = string cvarName +ptr GetMaxValuePtrPtr = string cvarName +bool HasDefaultValue = string cvarName +ptr GetDefaultValuePtr = string cvarName +void SetDefaultValue = string cvarName, ptr defaultValue +void SetDefaultValueString = string cvarName, string defaultValue \ No newline at end of file diff --git a/src/api/engine/convars/convars.h b/src/api/engine/convars/convars.h index caccd37bb..92950fa6e 100644 --- a/src/api/engine/convars/convars.h +++ b/src/api/engine/convars/convars.h @@ -47,6 +47,9 @@ class IConvarManager virtual bool ExistsConvar(std::string cvar_name) = 0; virtual EConVarType GetConvarType(std::string cvar_name) = 0; + virtual CVValue_t** GetMinValuePtrPtr(std::string cvar_name) = 0; + virtual CVValue_t** GetMaxValuePtrPtr(std::string cvar_name) = 0; + virtual void* GetConvarDataAddress(std::string cvar_name) = 0; virtual ConvarValue GetConvarValue(std::string cvar_name) = 0; diff --git a/src/engine/convars/convars.cpp b/src/engine/convars/convars.cpp index 8e355c800..5aa83ddfd 100644 --- a/src/engine/convars/convars.cpp +++ b/src/engine/convars/convars.cpp @@ -340,6 +340,19 @@ EConVarType CConvarManager::GetConvarType(std::string cvar_name) return cvar.GetType(); } + +CVValue_t** CConvarManager::GetMinValuePtrPtr(std::string cvar_name) +{ + ConVarRefAbstract cvar(cvar_name.c_str()); + return &cvar.GetConVarData()->m_minValue; +} + +CVValue_t** CConvarManager::GetMaxValuePtrPtr(std::string cvar_name) +{ + ConVarRefAbstract cvar(cvar_name.c_str()); + return &cvar.GetConVarData()->m_maxValue; +} + void* CConvarManager::GetConvarDataAddress(std::string cvar_name) { ConVarRefAbstract cvar(cvar_name.c_str()); diff --git a/src/engine/convars/convars.h b/src/engine/convars/convars.h index 6cb4409c4..786f15dc3 100644 --- a/src/engine/convars/convars.h +++ b/src/engine/convars/convars.h @@ -20,6 +20,7 @@ #define src_engine_convars_convars_h #include +#include #include class CConvarManager : public IConvarManager @@ -38,6 +39,9 @@ class CConvarManager : public IConvarManager virtual bool ExistsConvar(std::string cvar_name) override; virtual EConVarType GetConvarType(std::string cvar_name) override; + virtual CVValue_t** GetMinValuePtrPtr(std::string cvar_name) override; + virtual CVValue_t** GetMaxValuePtrPtr(std::string cvar_name) override; + virtual void* GetConvarDataAddress(std::string cvar_name) override; virtual ConvarValue GetConvarValue(std::string cvar_name) override; diff --git a/src/scripting/engine/convars.cpp b/src/scripting/engine/convars.cpp index 8d024193f..a2aefac32 100644 --- a/src/scripting/engine/convars.cpp +++ b/src/scripting/engine/convars.cpp @@ -17,6 +17,8 @@ ************************************************************************************************/ #include +#include +#include #include #include @@ -463,28 +465,16 @@ void Bridge_Convars_SetClientConvarValueString(int playerid, const char* convarN convarmanager->SetClientConvar(playerid, convarName, std::string(value)); } -void Bridge_Convars_AddFlags(const char* cvarName, uint64_t flags) -{ - auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - cvarmanager->AddFlags(cvarName, flags); -} - -void Bridge_Convars_RemoveFlags(const char* cvarName, uint64_t flags) -{ - auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - cvarmanager->RemoveFlags(cvarName, flags); -} - -void Bridge_Convars_ClearFlags(const char* cvarName) +uint64_t Bridge_Convars_GetFlags(const char* cvarName) { - auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - cvarmanager->ClearFlags(cvarName); + ConVarRefAbstract cvar(cvarName); + return cvar.GetConVarData()->m_nFlags; } -uint64_t Bridge_Convars_GetFlags(const char* cvarName) +void Bridge_Convars_SetFlags(const char* cvarName, uint64_t flags) { - auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return cvarmanager->GetFlags(cvarName); + ConVarRefAbstract cvar(cvarName); + cvar.GetConVarData()->m_nFlags = flags; } uint64_t Bridge_Convars_AddGlobalChangeListener(void* callback) @@ -529,6 +519,44 @@ void Bridge_Convars_RemoveConCommandCreatedListener(uint64_t listenerID) cvarmanager->RemoveConCommandCreatedListener(listenerID); } +void* Bridge_Convars_GetMinValuePtrPtr(const char* cvarName) +{ + auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); + return cvarmanager->GetMinValuePtrPtr(cvarName); +} + +void* Bridge_Convars_GetMaxValuePtrPtr(const char* cvarName) +{ + auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); + return cvarmanager->GetMaxValuePtrPtr(cvarName); +} + +bool Bridge_Convars_HasDefaultValue(const char* cvarName) +{ + ConVarRefAbstract cvar(cvarName); + return cvar.HasDefault(); +} + +void* Bridge_Convars_GetDefaultValuePtr(const char* cvarName) +{ + ConVarRefAbstract cvar(cvarName); + return cvar.GetConVarData()->DefaultValue(); +} + +void Bridge_Convars_SetDefaultValue(const char* cvarName, void* defaultValue) +{ + ConVarRefAbstract cvar(cvarName); + cvar.GetConVarData()->SetDefaultValue((CVValue_t*)defaultValue); +} + +void Bridge_Convars_SetDefaultValueString(const char* cvarName, const char* defaultValue) +{ + ConVarRefAbstract cvar(cvarName); + CUtlString string(defaultValue); + CVValue_t value(string); + cvar.GetConVarData()->SetDefaultValue(&value); +} + DEFINE_NATIVE("Convars.QueryClientConvar", Bridge_Convars_QueryClientConvar); DEFINE_NATIVE("Convars.AddQueryClientCvarCallback", Bridge_Convars_AddQueryClientCvarCallback); DEFINE_NATIVE("Convars.RemoveQueryClientCvarCallback", Bridge_Convars_RemoveQueryClientCvarCallback); @@ -602,7 +630,11 @@ DEFINE_NATIVE("Convars.SetClientConvarValueVector", Bridge_Convars_SetClientConv DEFINE_NATIVE("Convars.SetClientConvarValueVector4D", Bridge_Convars_SetClientConvarValueVector4D); DEFINE_NATIVE("Convars.SetClientConvarValueQAngle", Bridge_Convars_SetClientConvarValueQAngle); DEFINE_NATIVE("Convars.SetClientConvarValueString", Bridge_Convars_SetClientConvarValueString); -DEFINE_NATIVE("Convars.AddFlags", Bridge_Convars_AddFlags); -DEFINE_NATIVE("Convars.RemoveFlags", Bridge_Convars_RemoveFlags); -DEFINE_NATIVE("Convars.ClearFlags", Bridge_Convars_ClearFlags); -DEFINE_NATIVE("Convars.GetFlags", Bridge_Convars_GetFlags); \ No newline at end of file +DEFINE_NATIVE("Convars.GetFlags", Bridge_Convars_GetFlags); +DEFINE_NATIVE("Convars.SetFlags", Bridge_Convars_SetFlags); +DEFINE_NATIVE("Convars.GetMinValuePtrPtr", Bridge_Convars_GetMinValuePtrPtr); +DEFINE_NATIVE("Convars.GetMaxValuePtrPtr", Bridge_Convars_GetMaxValuePtrPtr); +DEFINE_NATIVE("Convars.HasDefaultValue", Bridge_Convars_HasDefaultValue); +DEFINE_NATIVE("Convars.GetDefaultValuePtr", Bridge_Convars_GetDefaultValuePtr); +DEFINE_NATIVE("Convars.SetDefaultValue", Bridge_Convars_SetDefaultValue); +DEFINE_NATIVE("Convars.SetDefaultValueString", Bridge_Convars_SetDefaultValueString); \ No newline at end of file diff --git a/vendor/s2sdk b/vendor/s2sdk index 02d5375f2..70ed7a6ac 160000 --- a/vendor/s2sdk +++ b/vendor/s2sdk @@ -1 +1 @@ -Subproject commit 02d5375f2b31e3ace36821844ce74c814ca55b7b +Subproject commit 70ed7a6acbe08f6c76a7a0668d70eee63c32ecf6 From 99556aa9cb95cd36ccdef32858fb9a0f37971302 Mon Sep 17 00:00:00 2001 From: samyyc Date: Sun, 9 Nov 2025 17:56:31 +0800 Subject: [PATCH 2/4] refactor(cvar): Remove overloads --- .../SwiftlyS2.Core/Modules/Convars/ConVar.cs | 228 ++------ .../SwiftlyS2.Core/Services/TestService.cs | 19 +- .../SwiftlyS2.Generated/Natives/Convars.cs | 506 ++---------------- .../Natives/Structs/CUtlString.cs | 1 - natives/engine/convars.native | 36 +- src/api/engine/convars/convars.h | 3 - src/engine/convars/convars.cpp | 13 - src/engine/convars/convars.h | 3 - src/scripting/engine/convars.cpp | 254 +-------- vendor/s2sdk | 2 +- 10 files changed, 128 insertions(+), 937 deletions(-) diff --git a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs index 7e1d79320..41070c968 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs @@ -80,188 +80,9 @@ public void ValidateType() } public T Value { - get { - if (typeof(T) == typeof(bool)) { - return (T)(object)NativeConvars.GetConvarValueBool(Name); - } - else if (typeof(T) == typeof(short)) { - return (T)(object)NativeConvars.GetConvarValueInt16(Name); - } - else if (typeof(T) == typeof(ushort)) { - return (T)(object)NativeConvars.GetConvarValueUInt16(Name); - } - else if (typeof(T) == typeof(int)) { - return (T)(object)NativeConvars.GetConvarValueInt32(Name); - } - else if (typeof(T) == typeof(uint)) { - return (T)(object)NativeConvars.GetConvarValueUInt32(Name); - } - else if (typeof(T) == typeof(float)) { - return (T)(object)NativeConvars.GetConvarValueFloat(Name); - } - else if (typeof(T) == typeof(long)) { - return (T)(object)NativeConvars.GetConvarValueInt64(Name); - } - else if (typeof(T) == typeof(ulong)) { - return (T)(object)NativeConvars.GetConvarValueUInt64(Name); - } - else if (typeof(T) == typeof(double)) { - return (T)(object)NativeConvars.GetConvarValueDouble(Name); - } - else if (typeof(T) == typeof(Color)) { - return (T)(object)NativeConvars.GetConvarValueColor(Name); - } - else if (typeof(T) == typeof(QAngle)) { - return (T)(object)NativeConvars.GetConvarValueQAngle(Name); - } - else if (typeof(T) == typeof(Vector)) { - return (T)(object)NativeConvars.GetConvarValueVector(Name); - } - else if (typeof(T) == typeof(Vector2D)) { - return (T)(object)NativeConvars.GetConvarValueVector2D(Name); - } - else if (typeof(T) == typeof(Vector4D)) { - return (T)(object)NativeConvars.GetConvarValueVector4D(Name); - } - else if (typeof(T) == typeof(string)) { - return (T)(object)NativeConvars.GetConvarValueString(Name); - } - throw new ArgumentException($"Invalid type {typeof(T).Name}"); - } - set { - if (value is bool boolValue) { - NativeConvars.SetConvarValueBool(Name, boolValue); - return; - } - else if (value is short shortValue) { - NativeConvars.SetConvarValueInt16(Name, shortValue); - return; - } - else if (value is ushort ushortValue) { - NativeConvars.SetConvarValueUInt16(Name, ushortValue); - return; - } - else if (value is int intValue) { - NativeConvars.SetConvarValueInt32(Name, intValue); - return; - } - else if (value is uint uintValue) { - NativeConvars.SetConvarValueUInt32(Name, uintValue); - return; - } - else if (value is float floatValue) { - NativeConvars.SetConvarValueFloat(Name, floatValue); - return; - } - else if (value is long longValue) { - NativeConvars.SetConvarValueInt64(Name, longValue); - return; - } - else if (value is ulong ulongValue) { - NativeConvars.SetConvarValueUInt64(Name, ulongValue); - return; - } - else if (value is double doubleValue) { - NativeConvars.SetConvarValueDouble(Name, doubleValue); - return; - } - else if (value is Color colorValue) { - NativeConvars.SetConvarValueColor(Name, colorValue); - return; - } - else if (value is QAngle qAngleValue) { - NativeConvars.SetConvarValueQAngle(Name, qAngleValue); - return; - } - else if (value is Vector vectorValue) { - NativeConvars.SetConvarValueVector(Name, vectorValue); - return; - } - else if (value is Vector2D vector2DValue) { - NativeConvars.SetConvarValueVector2D(Name, vector2DValue); - return; - } - else if (value is Vector4D vector4DValue) { - NativeConvars.SetConvarValueVector4D(Name, vector4DValue); - return; - } - else if (value is string stringValue) { - NativeConvars.SetConvarValueString(Name, stringValue); - return; - } - throw new ArgumentException($"Invalid type {typeof(T).Name}"); - } + get => GetValue(); + set => SetValue(value); } - - public void SetInternal(T value) - { - var addr = NativeConvars.GetConvarDataAddress(Name); - - if (addr == nint.Zero) { - throw new Exception($"Convar {Name} not found."); - } - - if (value is bool boolValue) { - addr.Write(boolValue); - return; - } - else if (value is short shortValue) { - addr.Write(shortValue); - return; - } - else if (value is ushort ushortValue) { - addr.Write(ushortValue); - return; - } - else if (value is int intValue) { - addr.Write(intValue); - return; - } - else if (value is float floatValue) { - addr.Write(floatValue); - return; - } - else if (value is long longValue) { - addr.Write(longValue); - return; - } - else if (value is ulong ulongValue) { - addr.Write(ulongValue); - return; - } - else if (value is double doubleValue) { - addr.Write(doubleValue); - return; - } - else if (value is Color colorValue) { - addr.Write(colorValue); - return; - } - else if (value is QAngle qAngleValue) { - addr.Write(qAngleValue); - return; - } - else if (value is Vector vectorValue) { - addr.Write(vectorValue); - return; - } - else if (value is Vector2D vector2DValue) { - addr.Write(vector2DValue); - return; - } - else if (value is Vector4D vector4DValue) { - addr.Write(vector4DValue); - return; - } - else if (value is string stringValue) - { - var ptr = StringPool.Allocate(stringValue); - addr.Write(ptr); - return; - } - throw new ArgumentException($"Invalid type {typeof(T).Name}"); - } - public void ReplicateToClient(int clientId, T value) { if (value is bool boolValue) { @@ -362,6 +183,51 @@ public void QueryClient(int clientId, Action callback) NativeConvars.QueryClientConvar(clientId, Name); } + public T GetValue() + { + unsafe { + if (Type != EConVarType.EConVarType_String) { + return *(T*)NativeConvars.GetValuePtr(Name); + } + else { + return (T)(object)(*(CUtlString*)NativeConvars.GetValuePtr(Name)).Value; + } + } + } + + public void SetValue(T value) + { + unsafe { + if (Type != EConVarType.EConVarType_String) { + NativeConvars.SetValuePtr(Name, (nint)(&value)); + } + else { + CUtlString str = new(); + str.Value = (string)(object)value; + NativeConvars.SetValuePtr(Name, (nint)(&str)); + } + } + } + + + public void SetInternal( T value ) + { + unsafe + { + if (Type != EConVarType.EConVarType_String) + { + NativeConvars.SetValueInternalPtr(Name, (nint)(&value)); + } + else + { + CUtlString str = new(); + str.Value = (string)(object)value; + NativeConvars.SetValueInternalPtr(Name, (nint)(&str)); + } + } + } + + public T GetMinValue() { if (!IsMinMaxType) { diff --git a/managed/src/SwiftlyS2.Core/Services/TestService.cs b/managed/src/SwiftlyS2.Core/Services/TestService.cs index 2c0869b62..42c2c8c32 100644 --- a/managed/src/SwiftlyS2.Core/Services/TestService.cs +++ b/managed/src/SwiftlyS2.Core/Services/TestService.cs @@ -55,21 +55,14 @@ public void Test() { _Core.Command.RegisterCommand("rrr", (context) => { - var a = _Core.ConVar.Create("test_convar", "Test convar", 123); + var a = _Core.ConVar.Create("test_convar", "Test convar", "abc"); - Console.WriteLine(a.Flags.HasFlag(ConvarFlags.DEVELOPMENT_ONLY)); + Console.WriteLine(a.Value); + a.SetInternal("ghi"); - // setting this to DEVELOPMENT_ONLY will cause a crash later - // because if its development only, the ConVarRefAbstract will not be able to find the ConvarData - // eventually return a nullptr in GetConvarData - a.Flags |= ConvarFlags.REPLICATED; - - Console.WriteLine(a.Flags.HasFlag(ConvarFlags.REPLICATED)); - Console.WriteLine(a.Flags.HasFlag(ConvarFlags.CHEAT)); - - Console.WriteLine(a.DefaultValue); - a.DefaultValue = 234; - Console.WriteLine(a.DefaultValue); + Console.WriteLine(a.Value); + a.Value = "def"; + Console.WriteLine(a.Value); }); // _Core.Event.OnItemServicesCanAcquireHook += (@event) => { // Console.WriteLine(@event.EconItemView.ItemDefinitionIndex); diff --git a/managed/src/SwiftlyS2.Generated/Natives/Convars.cs b/managed/src/SwiftlyS2.Generated/Natives/Convars.cs index ecff01781..8ea5e67d6 100644 --- a/managed/src/SwiftlyS2.Generated/Natives/Convars.cs +++ b/managed/src/SwiftlyS2.Generated/Natives/Convars.cs @@ -455,469 +455,6 @@ public unsafe static int GetConvarType(string cvarName) { } } - private unsafe static delegate* unmanaged _GetConvarDataAddress; - - public unsafe static nint GetConvarDataAddress(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarDataAddress(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueInt16; - - public unsafe static short GetConvarValueInt16(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueInt16(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueUInt16; - - public unsafe static ushort GetConvarValueUInt16(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueUInt16(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueInt32; - - public unsafe static int GetConvarValueInt32(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueInt32(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueUInt32; - - public unsafe static uint GetConvarValueUInt32(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueUInt32(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueInt64; - - public unsafe static long GetConvarValueInt64(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueInt64(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueUInt64; - - public unsafe static ulong GetConvarValueUInt64(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueUInt64(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueBool; - - public unsafe static bool GetConvarValueBool(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueBool(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret == 1; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueFloat; - - public unsafe static float GetConvarValueFloat(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueFloat(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueDouble; - - public unsafe static double GetConvarValueDouble(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueDouble(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueColor; - - public unsafe static Color GetConvarValueColor(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueColor(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueVector2D; - - public unsafe static Vector2D GetConvarValueVector2D(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueVector2D(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueVector; - - public unsafe static Vector GetConvarValueVector(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueVector(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueVector4D; - - public unsafe static Vector4D GetConvarValueVector4D(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueVector4D(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueQAngle; - - public unsafe static QAngle GetConvarValueQAngle(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueQAngle(cvarNameBufferPtr); - pool.Return(cvarNameBuffer); - return ret; - } - } - - private unsafe static delegate* unmanaged _GetConvarValueString; - - public unsafe static string GetConvarValueString(string cvarName) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - var ret = _GetConvarValueString(null, cvarNameBufferPtr); - var retBuffer = pool.Rent(ret + 1); - fixed (byte* retBufferPtr = retBuffer) { - ret = _GetConvarValueString(retBufferPtr, cvarNameBufferPtr); - var retString = Encoding.UTF8.GetString(retBufferPtr, ret); - pool.Return(retBuffer); - pool.Return(cvarNameBuffer); - return retString; - } - } - } - - private unsafe static delegate* unmanaged _SetConvarValueInt16; - - public unsafe static void SetConvarValueInt16(string cvarName, short defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueInt16(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueUInt16; - - public unsafe static void SetConvarValueUInt16(string cvarName, ushort defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueUInt16(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueInt32; - - public unsafe static void SetConvarValueInt32(string cvarName, int defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueInt32(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueUInt32; - - public unsafe static void SetConvarValueUInt32(string cvarName, uint defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueUInt32(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueInt64; - - public unsafe static void SetConvarValueInt64(string cvarName, long defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueInt64(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueUInt64; - - public unsafe static void SetConvarValueUInt64(string cvarName, ulong defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueUInt64(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueBool; - - public unsafe static void SetConvarValueBool(string cvarName, bool defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueBool(cvarNameBufferPtr, defaultValue ? (byte)1 : (byte)0); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueFloat; - - public unsafe static void SetConvarValueFloat(string cvarName, float defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueFloat(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueDouble; - - public unsafe static void SetConvarValueDouble(string cvarName, double defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueDouble(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueColor; - - public unsafe static void SetConvarValueColor(string cvarName, Color defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueColor(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueVector2D; - - public unsafe static void SetConvarValueVector2D(string cvarName, Vector2D defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueVector2D(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueVector; - - public unsafe static void SetConvarValueVector(string cvarName, Vector defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueVector(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueVector4D; - - public unsafe static void SetConvarValueVector4D(string cvarName, Vector4D defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueVector4D(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueQAngle; - - public unsafe static void SetConvarValueQAngle(string cvarName, QAngle defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - _SetConvarValueQAngle(cvarNameBufferPtr, defaultValue); - pool.Return(cvarNameBuffer); - } - } - - private unsafe static delegate* unmanaged _SetConvarValueString; - - public unsafe static void SetConvarValueString(string cvarName, string defaultValue) { - var pool = ArrayPool.Shared; - var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); - var cvarNameBuffer = pool.Rent(cvarNameLength + 1); - Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); - cvarNameBuffer[cvarNameLength] = 0; - var defaultValueLength = Encoding.UTF8.GetByteCount(defaultValue); - var defaultValueBuffer = pool.Rent(defaultValueLength + 1); - Encoding.UTF8.GetBytes(defaultValue, defaultValueBuffer); - defaultValueBuffer[defaultValueLength] = 0; - fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { - fixed (byte* defaultValueBufferPtr = defaultValueBuffer) { - _SetConvarValueString(cvarNameBufferPtr, defaultValueBufferPtr); - pool.Return(cvarNameBuffer); - pool.Return(defaultValueBuffer); - } - } - } - private unsafe static delegate* unmanaged _SetClientConvarValueInt16; public unsafe static void SetClientConvarValueInt16(int playerid, string cvarName, short defaultValue) { @@ -1258,4 +795,47 @@ public unsafe static void SetDefaultValueString(string cvarName, string defaultV } } } + + private unsafe static delegate* unmanaged _GetValuePtr; + + public unsafe static nint GetValuePtr(string cvarName) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + var ret = _GetValuePtr(cvarNameBufferPtr); + pool.Return(cvarNameBuffer); + return ret; + } + } + + private unsafe static delegate* unmanaged _SetValuePtr; + + public unsafe static void SetValuePtr(string cvarName, nint value) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + _SetValuePtr(cvarNameBufferPtr, value); + pool.Return(cvarNameBuffer); + } + } + + private unsafe static delegate* unmanaged _SetValueInternalPtr; + + public unsafe static void SetValueInternalPtr(string cvarName, nint value) { + var pool = ArrayPool.Shared; + var cvarNameLength = Encoding.UTF8.GetByteCount(cvarName); + var cvarNameBuffer = pool.Rent(cvarNameLength + 1); + Encoding.UTF8.GetBytes(cvarName, cvarNameBuffer); + cvarNameBuffer[cvarNameLength] = 0; + fixed (byte* cvarNameBufferPtr = cvarNameBuffer) { + _SetValueInternalPtr(cvarNameBufferPtr, value); + pool.Return(cvarNameBuffer); + } + } } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs b/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs index 2c51e8787..442905c9a 100644 --- a/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs +++ b/managed/src/SwiftlyS2.Shared/Natives/Structs/CUtlString.cs @@ -16,7 +16,6 @@ public string Value { return Marshal.PtrToStringUTF8(_ptr)!; } set => _ptr = StringPool.Allocate(value); - } public static implicit operator string(CUtlString str) => str.Value; diff --git a/natives/engine/convars.native b/natives/engine/convars.native index eddd1b092..b59906ac8 100644 --- a/natives/engine/convars.native +++ b/natives/engine/convars.native @@ -27,37 +27,6 @@ void CreateConvarString = string cvarName, int32 cvarType, uint64 cvarFlags, str void DeleteConvar = string cvarName bool ExistsConvar = string cvarName int32 GetConvarType = string cvarName -ptr GetConvarDataAddress = string cvarName -int16 GetConvarValueInt16 = string cvarName -uint16 GetConvarValueUInt16 = string cvarName -int32 GetConvarValueInt32 = string cvarName -uint32 GetConvarValueUInt32 = string cvarName -int64 GetConvarValueInt64 = string cvarName -uint64 GetConvarValueUInt64 = string cvarName -bool GetConvarValueBool = string cvarName -float GetConvarValueFloat = string cvarName -double GetConvarValueDouble = string cvarName -color GetConvarValueColor = string cvarName -vector2 GetConvarValueVector2D = string cvarName -vector GetConvarValueVector = string cvarName -vector4 GetConvarValueVector4D = string cvarName -qangle GetConvarValueQAngle = string cvarName -string GetConvarValueString = string cvarName -void SetConvarValueInt16 = string cvarName, int16 defaultValue -void SetConvarValueUInt16 = string cvarName, uint16 defaultValue -void SetConvarValueInt32 = string cvarName, int32 defaultValue -void SetConvarValueUInt32 = string cvarName, uint32 defaultValue -void SetConvarValueInt64 = string cvarName, int64 defaultValue -void SetConvarValueUInt64 = string cvarName, uint64 defaultValue -void SetConvarValueBool = string cvarName, bool defaultValue -void SetConvarValueFloat = string cvarName, float defaultValue -void SetConvarValueDouble = string cvarName, double defaultValue -void SetConvarValueColor = string cvarName, color defaultValue -void SetConvarValueVector2D = string cvarName, vector2 defaultValue -void SetConvarValueVector = string cvarName, vector defaultValue -void SetConvarValueVector4D = string cvarName, vector4 defaultValue -void SetConvarValueQAngle = string cvarName, qangle defaultValue -void SetConvarValueString = string cvarName, string defaultValue void SetClientConvarValueInt16 = int32 playerid, string cvarName, int16 defaultValue void SetClientConvarValueUInt16 = int32 playerid, string cvarName, uint16 defaultValue void SetClientConvarValueInt32 = int32 playerid, string cvarName, int32 defaultValue @@ -80,4 +49,7 @@ ptr GetMaxValuePtrPtr = string cvarName bool HasDefaultValue = string cvarName ptr GetDefaultValuePtr = string cvarName void SetDefaultValue = string cvarName, ptr defaultValue -void SetDefaultValueString = string cvarName, string defaultValue \ No newline at end of file +void SetDefaultValueString = string cvarName, string defaultValue +ptr GetValuePtr = string cvarName +void SetValuePtr = string cvarName, ptr value +void SetValueInternalPtr = string cvarName, ptr value \ No newline at end of file diff --git a/src/api/engine/convars/convars.h b/src/api/engine/convars/convars.h index 92950fa6e..caccd37bb 100644 --- a/src/api/engine/convars/convars.h +++ b/src/api/engine/convars/convars.h @@ -47,9 +47,6 @@ class IConvarManager virtual bool ExistsConvar(std::string cvar_name) = 0; virtual EConVarType GetConvarType(std::string cvar_name) = 0; - virtual CVValue_t** GetMinValuePtrPtr(std::string cvar_name) = 0; - virtual CVValue_t** GetMaxValuePtrPtr(std::string cvar_name) = 0; - virtual void* GetConvarDataAddress(std::string cvar_name) = 0; virtual ConvarValue GetConvarValue(std::string cvar_name) = 0; diff --git a/src/engine/convars/convars.cpp b/src/engine/convars/convars.cpp index 5aa83ddfd..8e355c800 100644 --- a/src/engine/convars/convars.cpp +++ b/src/engine/convars/convars.cpp @@ -340,19 +340,6 @@ EConVarType CConvarManager::GetConvarType(std::string cvar_name) return cvar.GetType(); } - -CVValue_t** CConvarManager::GetMinValuePtrPtr(std::string cvar_name) -{ - ConVarRefAbstract cvar(cvar_name.c_str()); - return &cvar.GetConVarData()->m_minValue; -} - -CVValue_t** CConvarManager::GetMaxValuePtrPtr(std::string cvar_name) -{ - ConVarRefAbstract cvar(cvar_name.c_str()); - return &cvar.GetConVarData()->m_maxValue; -} - void* CConvarManager::GetConvarDataAddress(std::string cvar_name) { ConVarRefAbstract cvar(cvar_name.c_str()); diff --git a/src/engine/convars/convars.h b/src/engine/convars/convars.h index 786f15dc3..c4dfeee88 100644 --- a/src/engine/convars/convars.h +++ b/src/engine/convars/convars.h @@ -39,9 +39,6 @@ class CConvarManager : public IConvarManager virtual bool ExistsConvar(std::string cvar_name) override; virtual EConVarType GetConvarType(std::string cvar_name) override; - virtual CVValue_t** GetMinValuePtrPtr(std::string cvar_name) override; - virtual CVValue_t** GetMaxValuePtrPtr(std::string cvar_name) override; - virtual void* GetConvarDataAddress(std::string cvar_name) override; virtual ConvarValue GetConvarValue(std::string cvar_name) override; diff --git a/src/scripting/engine/convars.cpp b/src/scripting/engine/convars.cpp index a2aefac32..93924d40b 100644 --- a/src/scripting/engine/convars.cpp +++ b/src/scripting/engine/convars.cpp @@ -184,197 +184,6 @@ int Bridge_Convars_GetConvarType(const char* convarName) return (int)(convarmanager->GetConvarType(convarName)); } -void* Bridge_Convars_GetConvarDataAddress(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return convarmanager->GetConvarDataAddress(convarName); -} - -int16_t Bridge_Convars_GetConvarValueInt16(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -uint16_t Bridge_Convars_GetConvarValueUInt16(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -int32_t Bridge_Convars_GetConvarValueInt32(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -uint32_t Bridge_Convars_GetConvarValueUInt32(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -int64_t Bridge_Convars_GetConvarValueInt64(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -uint64_t Bridge_Convars_GetConvarValueUInt64(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -bool Bridge_Convars_GetConvarValueBool(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -float Bridge_Convars_GetConvarValueFloat(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -double Bridge_Convars_GetConvarValueDouble(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -Color Bridge_Convars_GetConvarValueColor(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -Vector2D Bridge_Convars_GetConvarValueVector2D(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -Vector Bridge_Convars_GetConvarValueVector(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -Vector4D Bridge_Convars_GetConvarValueVector4D(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -QAngle Bridge_Convars_GetConvarValueQAngle(const char* convarName) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return std::get(convarmanager->GetConvarValue(convarName)); -} - -int Bridge_Convars_GetConvarValueString(char* out, const char* convarName, const char* value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - static std::string s; - s = std::get(convarmanager->GetConvarValue(convarName)); - - if (out != nullptr) strcpy(out, s.c_str()); - - return s.size(); -} - -void Bridge_Convars_SetConvarValueInt16(const char* convarName, int16_t value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueUInt16(const char* convarName, uint16_t value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueInt32(const char* convarName, int32_t value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueUInt32(const char* convarName, uint32_t value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueInt64(const char* convarName, int64_t value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueUInt64(const char* convarName, uint64_t value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueBool(const char* convarName, bool value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueFloat(const char* convarName, float value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueDouble(const char* convarName, double value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueColor(const char* convarName, Color value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueVector2D(const char* convarName, Vector2D value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueVector(const char* convarName, Vector value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueVector4D(const char* convarName, Vector4D value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueQAngle(const char* convarName, QAngle value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, value); -} - -void Bridge_Convars_SetConvarValueString(const char* convarName, const char* value) -{ - static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - convarmanager->SetConvarValue(convarName, std::string(value)); -} - void Bridge_Convars_SetClientConvarValueInt16(int playerid, const char* convarName, int16_t value) { static auto convarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); @@ -521,14 +330,14 @@ void Bridge_Convars_RemoveConCommandCreatedListener(uint64_t listenerID) void* Bridge_Convars_GetMinValuePtrPtr(const char* cvarName) { - auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return cvarmanager->GetMinValuePtrPtr(cvarName); + ConVarRefAbstract cvar(cvarName); + return &cvar.GetConVarData()->m_minValue; } void* Bridge_Convars_GetMaxValuePtrPtr(const char* cvarName) { - auto cvarmanager = g_ifaceService.FetchInterface(CONVARMANAGER_INTERFACE_VERSION); - return cvarmanager->GetMaxValuePtrPtr(cvarName); + ConVarRefAbstract cvar(cvarName); + return &cvar.GetConVarData()->m_maxValue; } bool Bridge_Convars_HasDefaultValue(const char* cvarName) @@ -557,6 +366,25 @@ void Bridge_Convars_SetDefaultValueString(const char* cvarName, const char* defa cvar.GetConVarData()->SetDefaultValue(&value); } +void* Bridge_Convars_GetValuePtr(const char* cvarName) +{ + ConVarRefAbstract cvar(cvarName); + return cvar.GetConVarData()->Value(0); +} + +void Bridge_Convars_SetValuePtr(const char* cvarName, void* value) +{ + ConVarRefAbstract cvar(cvarName); + cvar.SetOrQueueValueInternal(0, (CVValue_t*)value); +} + + +void Bridge_Convars_SetValueInternalPtr(const char* cvarName, void* value) +{ + ConVarRefAbstract cvar(cvarName); + cvar.SetValueInternal(0, (CVValue_t*)value); +} + DEFINE_NATIVE("Convars.QueryClientConvar", Bridge_Convars_QueryClientConvar); DEFINE_NATIVE("Convars.AddQueryClientCvarCallback", Bridge_Convars_AddQueryClientCvarCallback); DEFINE_NATIVE("Convars.RemoveQueryClientCvarCallback", Bridge_Convars_RemoveQueryClientCvarCallback); @@ -584,37 +412,6 @@ DEFINE_NATIVE("Convars.CreateConvarString", Bridge_Convars_CreateConvarString); DEFINE_NATIVE("Convars.DeleteConvar", Bridge_Convars_DeleteConvar); DEFINE_NATIVE("Convars.ExistsConvar", Bridge_Convars_ExistsConvar); DEFINE_NATIVE("Convars.GetConvarType", Bridge_Convars_GetConvarType); -DEFINE_NATIVE("Convars.GetConvarDataAddress", Bridge_Convars_GetConvarDataAddress); -DEFINE_NATIVE("Convars.GetConvarValueInt16", Bridge_Convars_GetConvarValueInt16); -DEFINE_NATIVE("Convars.GetConvarValueUInt16", Bridge_Convars_GetConvarValueUInt16); -DEFINE_NATIVE("Convars.GetConvarValueInt32", Bridge_Convars_GetConvarValueInt32); -DEFINE_NATIVE("Convars.GetConvarValueUInt32", Bridge_Convars_GetConvarValueUInt32); -DEFINE_NATIVE("Convars.GetConvarValueInt64", Bridge_Convars_GetConvarValueInt64); -DEFINE_NATIVE("Convars.GetConvarValueUInt64", Bridge_Convars_GetConvarValueUInt64); -DEFINE_NATIVE("Convars.GetConvarValueBool", Bridge_Convars_GetConvarValueBool); -DEFINE_NATIVE("Convars.GetConvarValueFloat", Bridge_Convars_GetConvarValueFloat); -DEFINE_NATIVE("Convars.GetConvarValueDouble", Bridge_Convars_GetConvarValueDouble); -DEFINE_NATIVE("Convars.GetConvarValueColor", Bridge_Convars_GetConvarValueColor); -DEFINE_NATIVE("Convars.GetConvarValueVector2D", Bridge_Convars_GetConvarValueVector2D); -DEFINE_NATIVE("Convars.GetConvarValueVector", Bridge_Convars_GetConvarValueVector); -DEFINE_NATIVE("Convars.GetConvarValueVector4D", Bridge_Convars_GetConvarValueVector4D); -DEFINE_NATIVE("Convars.GetConvarValueQAngle", Bridge_Convars_GetConvarValueQAngle); -DEFINE_NATIVE("Convars.GetConvarValueString", Bridge_Convars_GetConvarValueString); -DEFINE_NATIVE("Convars.SetConvarValueInt16", Bridge_Convars_SetConvarValueInt16); -DEFINE_NATIVE("Convars.SetConvarValueUInt16", Bridge_Convars_SetConvarValueUInt16); -DEFINE_NATIVE("Convars.SetConvarValueInt32", Bridge_Convars_SetConvarValueInt32); -DEFINE_NATIVE("Convars.SetConvarValueUInt32", Bridge_Convars_SetConvarValueUInt32); -DEFINE_NATIVE("Convars.SetConvarValueInt64", Bridge_Convars_SetConvarValueInt64); -DEFINE_NATIVE("Convars.SetConvarValueUInt64", Bridge_Convars_SetConvarValueUInt64); -DEFINE_NATIVE("Convars.SetConvarValueBool", Bridge_Convars_SetConvarValueBool); -DEFINE_NATIVE("Convars.SetConvarValueFloat", Bridge_Convars_SetConvarValueFloat); -DEFINE_NATIVE("Convars.SetConvarValueDouble", Bridge_Convars_SetConvarValueDouble); -DEFINE_NATIVE("Convars.SetConvarValueColor", Bridge_Convars_SetConvarValueColor); -DEFINE_NATIVE("Convars.SetConvarValueVector2D", Bridge_Convars_SetConvarValueVector2D); -DEFINE_NATIVE("Convars.SetConvarValueVector", Bridge_Convars_SetConvarValueVector); -DEFINE_NATIVE("Convars.SetConvarValueVector4D", Bridge_Convars_SetConvarValueVector4D); -DEFINE_NATIVE("Convars.SetConvarValueQAngle", Bridge_Convars_SetConvarValueQAngle); -DEFINE_NATIVE("Convars.SetConvarValueString", Bridge_Convars_SetConvarValueString); DEFINE_NATIVE("Convars.SetClientConvarValueInt16", Bridge_Convars_SetClientConvarValueInt16); DEFINE_NATIVE("Convars.SetClientConvarValueUInt16", Bridge_Convars_SetClientConvarValueUInt16); DEFINE_NATIVE("Convars.SetClientConvarValueInt32", Bridge_Convars_SetClientConvarValueInt32); @@ -637,4 +434,7 @@ DEFINE_NATIVE("Convars.GetMaxValuePtrPtr", Bridge_Convars_GetMaxValuePtrPtr); DEFINE_NATIVE("Convars.HasDefaultValue", Bridge_Convars_HasDefaultValue); DEFINE_NATIVE("Convars.GetDefaultValuePtr", Bridge_Convars_GetDefaultValuePtr); DEFINE_NATIVE("Convars.SetDefaultValue", Bridge_Convars_SetDefaultValue); -DEFINE_NATIVE("Convars.SetDefaultValueString", Bridge_Convars_SetDefaultValueString); \ No newline at end of file +DEFINE_NATIVE("Convars.SetDefaultValueString", Bridge_Convars_SetDefaultValueString); +DEFINE_NATIVE("Convars.GetValuePtr", Bridge_Convars_GetValuePtr); +DEFINE_NATIVE("Convars.SetValuePtr", Bridge_Convars_SetValuePtr); +DEFINE_NATIVE("Convars.SetValueInternalPtr", Bridge_Convars_SetValueInternalPtr); \ No newline at end of file diff --git a/vendor/s2sdk b/vendor/s2sdk index 70ed7a6ac..de3c70be7 160000 --- a/vendor/s2sdk +++ b/vendor/s2sdk @@ -1 +1 @@ -Subproject commit 70ed7a6acbe08f6c76a7a0668d70eee63c32ecf6 +Subproject commit de3c70be718fb622e98c49c63dbe097c6e941039 From 62fd5461613a8740ae1053a18d5a27b018c622fb Mon Sep 17 00:00:00 2001 From: samyyc Date: Sun, 9 Nov 2025 18:13:06 +0800 Subject: [PATCH 3/4] feat(managed): More method in convar --- .../Modules/Convars/ConVarService.cs | 159 ++++++++++++------ .../SwiftlyS2.Core/Services/TestService.cs | 7 + .../Modules/Convars/IConVarService.cs | 24 +++ 3 files changed, 140 insertions(+), 50 deletions(-) diff --git a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVarService.cs b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVarService.cs index 1bc6a3cfc..e916a6318 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVarService.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVarService.cs @@ -25,11 +25,14 @@ internal enum EConVarType : int EConVarType_MAX }; -internal class ConVarService : IConVarService { +internal class ConVarService : IConVarService +{ - public IConVar? Find(string name) { + public IConVar? Find( string name ) + { - if (!NativeConvars.ExistsConvar(name)) { + if (!NativeConvars.ExistsConvar(name)) + { return null; } @@ -37,179 +40,235 @@ internal class ConVarService : IConVarService { } - public IConVar Create(string name, string helpMessage, T defaultValue, ConvarFlags flags = ConvarFlags.NONE) { - if (NativeConvars.ExistsConvar(name)) { + public IConVar Create( string name, string helpMessage, T defaultValue, ConvarFlags flags = ConvarFlags.NONE ) + { + if (NativeConvars.ExistsConvar(name)) + { throw new Exception($"Convar {name} already exists."); } - if (defaultValue is bool boolValue) { + if (defaultValue is bool boolValue) + { NativeConvars.CreateConvarBool(name, (int)EConVarType.EConVarType_Bool, (ulong)flags, helpMessage, boolValue, 0, 0); } - else if (defaultValue is short shortValue) { + else if (defaultValue is short shortValue) + { NativeConvars.CreateConvarInt16(name, (int)EConVarType.EConVarType_Int16, (ulong)flags, helpMessage, shortValue, 0, 0); } - else if (defaultValue is ushort ushortValue) { + else if (defaultValue is ushort ushortValue) + { NativeConvars.CreateConvarUInt16(name, (int)EConVarType.EConVarType_UInt16, (ulong)flags, helpMessage, ushortValue, 0, 0); } - else if (defaultValue is int intValue) { + else if (defaultValue is int intValue) + { NativeConvars.CreateConvarInt32(name, (int)EConVarType.EConVarType_Int32, (ulong)flags, helpMessage, intValue, 0, 0); } - else if (defaultValue is uint uintValue) { + else if (defaultValue is uint uintValue) + { NativeConvars.CreateConvarUInt32(name, (int)EConVarType.EConVarType_UInt32, (ulong)flags, helpMessage, uintValue, 0, 0); } - else if (defaultValue is long longValue) { + else if (defaultValue is long longValue) + { NativeConvars.CreateConvarInt64(name, (int)EConVarType.EConVarType_Int64, (ulong)flags, helpMessage, longValue, 0, 0); } - else if (defaultValue is ulong ulongValue) { + else if (defaultValue is ulong ulongValue) + { NativeConvars.CreateConvarUInt64(name, (int)EConVarType.EConVarType_UInt64, (ulong)flags, helpMessage, ulongValue, 0, 0); } - else if (defaultValue is float floatValue) { + else if (defaultValue is float floatValue) + { NativeConvars.CreateConvarFloat(name, (int)EConVarType.EConVarType_Float32, (ulong)flags, helpMessage, floatValue, 0, 0); } - else if (defaultValue is double doubleValue) { + else if (defaultValue is double doubleValue) + { NativeConvars.CreateConvarDouble(name, (int)EConVarType.EConVarType_Float64, (ulong)flags, helpMessage, doubleValue, 0, 0); } - else if (defaultValue is Vector2D vector2Value) { + else if (defaultValue is Vector2D vector2Value) + { NativeConvars.CreateConvarVector2D(name, (int)EConVarType.EConVarType_Vector2, (ulong)flags, helpMessage, vector2Value, 0, 0); } - else if (defaultValue is Vector vector3Value) { + else if (defaultValue is Vector vector3Value) + { NativeConvars.CreateConvarVector(name, (int)EConVarType.EConVarType_Vector3, (ulong)flags, helpMessage, vector3Value, 0, 0); } - else if (defaultValue is Vector4D vector4Value) { + else if (defaultValue is Vector4D vector4Value) + { NativeConvars.CreateConvarVector4D(name, (int)EConVarType.EConVarType_Vector4, (ulong)flags, helpMessage, vector4Value, 0, 0); } - else if (defaultValue is QAngle qAngleValue) { + else if (defaultValue is QAngle qAngleValue) + { NativeConvars.CreateConvarQAngle(name, (int)EConVarType.EConVarType_Qangle, (ulong)flags, helpMessage, qAngleValue, 0, 0); } - else if (defaultValue is Color colorValue) { + else if (defaultValue is Color colorValue) + { NativeConvars.CreateConvarColor(name, (int)EConVarType.EConVarType_Color, (ulong)flags, helpMessage, colorValue, 0, 0); } - else if (defaultValue is string stringValue) { + else if (defaultValue is string stringValue) + { NativeConvars.CreateConvarString(name, (int)EConVarType.EConVarType_String, (ulong)flags, helpMessage, stringValue, 0, 0); } - else { + else + { throw new Exception($"Unsupported type {typeof(T)}."); } return new ConVar(name); } - - public IConVar Create(string name, string helpMessage, T defaultValue, T? minValue = null, T? maxValue = null, ConvarFlags flags = ConvarFlags.NONE) where T : unmanaged { - if (NativeConvars.ExistsConvar(name)) { + public IConVar Create( string name, string helpMessage, T defaultValue, T? minValue, T? maxValue, ConvarFlags flags = ConvarFlags.NONE ) where T : unmanaged + { + + if (NativeConvars.ExistsConvar(name)) + { throw new Exception($"Convar {name} already exists."); } - unsafe { + unsafe + { - if (defaultValue is short shortValue) { + if (defaultValue is short shortValue) + { short* pMin = stackalloc short[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (short)(object)minValue.Value; } short* pMax = stackalloc short[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (short)(object)maxValue.Value; } NativeConvars.CreateConvarInt16(name, (int)EConVarType.EConVarType_Int16, (ulong)flags, helpMessage, shortValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is ushort ushortValue) { + else if (defaultValue is ushort ushortValue) + { ushort* pMin = stackalloc ushort[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (ushort)(object)minValue.Value; } ushort* pMax = stackalloc ushort[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (ushort)(object)maxValue.Value; } NativeConvars.CreateConvarUInt16(name, (int)EConVarType.EConVarType_UInt16, (ulong)flags, helpMessage, ushortValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is int intValue) { + else if (defaultValue is int intValue) + { int* pMin = stackalloc int[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (int)(object)minValue.Value; } int* pMax = stackalloc int[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (int)(object)maxValue.Value; } NativeConvars.CreateConvarInt32(name, (int)EConVarType.EConVarType_Int32, (ulong)flags, helpMessage, intValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is uint uintValue) { + else if (defaultValue is uint uintValue) + { uint* pMin = stackalloc uint[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (uint)(object)minValue.Value; } uint* pMax = stackalloc uint[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (uint)(object)maxValue.Value; } NativeConvars.CreateConvarUInt32(name, (int)EConVarType.EConVarType_UInt32, (ulong)flags, helpMessage, uintValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is long longValue) { + else if (defaultValue is long longValue) + { long* pMin = stackalloc long[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (long)(object)minValue.Value; } long* pMax = stackalloc long[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (long)(object)maxValue.Value; } NativeConvars.CreateConvarInt64(name, (int)EConVarType.EConVarType_Int64, (ulong)flags, helpMessage, longValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is ulong ulongValue) { + else if (defaultValue is ulong ulongValue) + { ulong* pMin = stackalloc ulong[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (ulong)(object)minValue.Value; } ulong* pMax = stackalloc ulong[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (ulong)(object)maxValue.Value; } NativeConvars.CreateConvarUInt64(name, (int)EConVarType.EConVarType_UInt64, (ulong)flags, helpMessage, ulongValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is float floatValue) { + else if (defaultValue is float floatValue) + { float* pMin = stackalloc float[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (float)(object)minValue.Value; } float* pMax = stackalloc float[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (float)(object)maxValue.Value; } NativeConvars.CreateConvarFloat(name, (int)EConVarType.EConVarType_Float32, (ulong)flags, helpMessage, floatValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else if (defaultValue is double doubleValue) { + else if (defaultValue is double doubleValue) + { double* pMin = stackalloc double[1]; - if (minValue.HasValue) { + if (minValue.HasValue) + { pMin[0] = (double)(object)minValue.Value; } double* pMax = stackalloc double[1]; - if (maxValue.HasValue) { + if (maxValue.HasValue) + { pMax[0] = (double)(object)maxValue.Value; } NativeConvars.CreateConvarDouble(name, (int)EConVarType.EConVarType_Float64, (ulong)flags, helpMessage, doubleValue, minValue.HasValue ? (nint)pMin : 0, maxValue.HasValue ? (nint)pMax : 0); } - else { + else + { throw new Exception($"You can't assign min and max values to {typeof(T)}."); } } return new ConVar(name); } + + public IConVar CreateOrFind( string name, string helpMessage, T defaultValue, ConvarFlags flags = ConvarFlags.NONE ) + { + return NativeConvars.ExistsConvar(name) ? new ConVar(name) : Create(name, helpMessage, defaultValue, flags); + } + + public IConVar CreateOrFind( string name, string helpMessage, T defaultValue, T? minValue, T? maxValue, ConvarFlags flags = ConvarFlags.NONE ) where T : unmanaged + { + return NativeConvars.ExistsConvar(name) ? new ConVar(name) : Create(name, helpMessage, defaultValue, minValue, maxValue, flags); + } } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Core/Services/TestService.cs b/managed/src/SwiftlyS2.Core/Services/TestService.cs index 42c2c8c32..04b96878c 100644 --- a/managed/src/SwiftlyS2.Core/Services/TestService.cs +++ b/managed/src/SwiftlyS2.Core/Services/TestService.cs @@ -53,8 +53,15 @@ ISwiftlyCore core public void Test() { + _Core.Event.OnEntityDeleted += (@event) => { + Console.WriteLine("Entity deleted: " + @event.Entity.Entity?.DesignerName); + }; _Core.Command.RegisterCommand("rrr", (context) => { + _Core.EntitySystem.GetAllEntities().ToList().ForEach(entity => { + entity.Entity.Flags |= 0x200; + }); + var a = _Core.ConVar.Create("test_convar", "Test convar", "abc"); Console.WriteLine(a.Value); diff --git a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs index bd1fa0ba2..38bbafd6a 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVarService.cs @@ -34,4 +34,28 @@ public interface IConVarService { /// The max value of the convar. /// The created convar. IConVar Create(string name, string helpMessage, T defaultValue, T? minValue, T? maxValue, ConvarFlags flags = ConvarFlags.NONE) where T: unmanaged; + + /// + /// Create a new convar or find an existing one by name. + /// + /// The type of the convar. + /// The name of the convar. + /// The help message of the convar. + /// The default value of the convar. + /// The flags of the convar. + /// The created or found convar. + IConVar CreateOrFind(string name, string helpMessage, T defaultValue, ConvarFlags flags = ConvarFlags.NONE); + + /// + /// Create a new convar or find an existing one by name with min and max values. + /// + /// The type of the convar. + /// The name of the convar. + /// The help message of the convar. + /// The default value of the convar. + /// The min value of the convar. + /// The max value of the convar. + /// The flags of the convar. + /// The created or found convar. + IConVar CreateOrFind(string name, string helpMessage, T defaultValue, T? minValue, T? maxValue, ConvarFlags flags = ConvarFlags.NONE) where T: unmanaged; } \ No newline at end of file From b5ea3824ef9dba5519f93d8fb097e6fbdc68a946 Mon Sep 17 00:00:00 2001 From: samyyc Date: Sun, 9 Nov 2025 18:16:19 +0800 Subject: [PATCH 4/4] feat(managed): Add try method to convar --- .../SwiftlyS2.Core/Modules/Convars/ConVar.cs | 38 +++++++++++++++++++ .../Modules/Convars/IConVar.cs | 21 ++++++++++ 2 files changed, 59 insertions(+) diff --git a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs index 41070c968..19df9fff0 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs @@ -313,4 +313,42 @@ public void SetDefaultValue(T defaultValue) } } } + + public bool TryGetMinValue(out T minValue) + { + if (!IsMinMaxType) { + minValue = default; + return false; + } + if (!HasMinValue) { + minValue = default; + return false; + } + minValue = GetMinValue(); + return true; + } + + public bool TryGetMaxValue(out T maxValue) + { + if (!IsMinMaxType) { + maxValue = default; + return false; + } + if (!HasMaxValue) { + maxValue = default; + return false; + } + maxValue = GetMaxValue(); + return true; + } + + public bool TryGetDefaultValue(out T defaultValue) + { + if (!HasDefaultValue) { + defaultValue = default; + return false; + } + defaultValue = GetDefaultValue(); + return true; + } } diff --git a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs index 0c8b2b9b5..4ad0ef09e 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Convars/IConVar.cs @@ -69,4 +69,25 @@ public interface IConVar { /// /// The action to execute with the value. void QueryClient(int clientId, Action callback); + + /// + /// Try to get the min value of the convar. + /// + /// The min value of the convar. + /// True if the min value is found, false otherwise. + bool TryGetMinValue(out T minValue); + + /// + /// Try to get the max value of the convar. + /// + /// The max value of the convar. + /// True if the max value is found, false otherwise. + bool TryGetMaxValue(out T maxValue); + + /// + /// Try to get the default value of the convar. + /// + /// The default value of the convar. + /// True if the default value is found, false otherwise. + bool TryGetDefaultValue(out T defaultValue); } \ No newline at end of file