Skip to content

feat: add Convar<T> for real convar creation/deletion/access - #935

Open
roflmuffin wants to merge 20 commits into
mainfrom
feature/real-convars
Open

roflmuffin wants to merge 20 commits into
mainfrom
feature/real-convars

Conversation

@roflmuffin

@roflmuffin roflmuffin commented Jul 14, 2025 •

Copy link
Copy Markdown
Owner

This PR adds Convar<T> which is a strongly typed variant of ConVar which provides better safety (no raw pointer accesses), as well as the ability to create real-convars that exist within the engine (and can be found using find foo in the console) amongst other things.

TODO:

  • Add BasePlugin based registration so that convars are automatically unloaded (similar to FakeConvar). Should the .Create static be restricted?

@roflmuffin
roflmuffin force-pushed the feature/real-convars branch from f7cd192 to 8d9ea3f Compare July 20, 2025 11:17

@ubbemir ubbemir left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome. Would be great to also have a list of known ConVars that utilize this to reduce mistake of accidentally using the wrong type with a ConVar. This however would be fitting in another PR I suppose.

ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.Push(flags);
ScriptContext.GlobalScriptContext.SetIdentifier(0xB2BDCCBF);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic numbers should not be written by themselves. Maybe make them a constant with a name to clarify?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are hash calculated native identifiers

@KillStr3aK

Copy link
Copy Markdown
Contributor

This looks awesome. Would be great to also have a list of known ConVars that utilize this to reduce mistake of accidentally using the wrong type with a ConVar. This however would be fitting in another PR I suppose.

https://cs2.poggu.me/dumped-data/convar-list

@ubbemir

ubbemir commented Jul 31, 2025 •

Copy link
Copy Markdown

This looks awesome. Would be great to also have a list of known ConVars that utilize this to reduce mistake of accidentally using the wrong type with a ConVar. This however would be fitting in another PR I suppose.

https://cs2.poggu.me/dumped-data/convar-list

Yes I know of that. But implement some of these at least into C# as statically typed to make use of the strength of static typing and static code analysis to reduce mistakes and catch erronous usage at compile time.

For example would it be suitable to do something similar to this?

public static class KnownConVars
{
    public static ConVar<bool> SvCheats = new ConVar<bool>("sv_cheats");
    public static ConVar<int> MpWarmupTime = new ConVar<int>("mp_warmuptime");
    public static ConVar<float> MaxSpeed = new ConVar<float>("sv_maxspeed");

    // Example: Add other ConVars here...
}

This comment was marked as outdated.

This comment was marked as outdated.

This comment was marked as outdated.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Null native objects can crash the host, deletion can invalidate engine-owned ConVars, and native allocations are leaked.

Review effort: Balanced
Findings: 3 High severity

Open (3)
Resolved since last review (1)
Previously missed (4)

In code that hasn't changed since last review

Medium severity Unload misses ConVars stored in base or derived fields

managed/​CounterStrikeSharp.API/​Core/​BasePlugin.cs:564

Filtering on an exact declared ConVar<> type skips owned values stored in a ConVarBase field or a subclass of ConVar<T>, so those public plugin fields are never deleted on unload. The loop already checks the runtime value and Owned; select every field assignable to ConVarBase instead.

Medium severity Returned vector values bypass validation and expose storage

managed/​CounterStrikeSharp.API/​Modules/​Cvars/​ConVarOfT.cs:288

For vector and angle types this returns a NativeObject backed directly by the engine's value pointer. Mutating the returned object's components therefore changes the ConVar without going through SetAs, bypassing bounds enforcement and OnConVarChanged notifications; retaining it also exposes storage after deletion. Return a detached value copy (or an immutable view) so mutations must use the Value setter.

Medium severity Created ConVar wrappers are leaked

src/​scripting/​natives/​natives_convars.cpp:624

Each creation branch allocates a CConVar<T> with new, but this pointer is only kept in this local variable and is discarded when the native returns. DeleteConVar merely calls Invalidate(), so repeated plugin reloads or create/delete cycles permanently leak every allocated wrapper (and potentially its owned storage). Keep the created object in an ownership registry and destroy it during deletion/shutdown.

Low severity Deletion sentinel comment is incorrect

managed/​CounterStrikeSharp.Tests.Native/​RealConVarTests.cs:33

This comment names the wrong deletion sentinel: ConVarBase.Delete sets AccessIndex to ushort.MaxValue, matching the check below, not zero.

Comment thread managed/CounterStrikeSharp.API/Modules/Cvars/ConVarOfT.cs
Comment thread managed/CounterStrikeSharp.API/Modules/Cvars/ConVarOfT.cs
Comment thread managed/CounterStrikeSharp.API/Modules/Cvars/ConVarOfT.cs
Add null checks for DefaultValue and value parameters in Create and setter methods.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants