Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ set(SOURCE_FILES
src/core/managers/con_command_manager.cpp
src/core/managers/con_command_manager.h
src/scripting/natives/natives_commands.cpp
src/scripting/natives/natives_convars.cpp
src/core/memory_module.h
src/core/memory_module.cpp
src/core/cs2_sdk/interfaces/cgameresourceserviceserver.h
Expand Down
140 changes: 140 additions & 0 deletions managed/CounterStrikeSharp.API/Core/API.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,146 @@ public static void ReplicateConvar(int clientslot, string convarname, string con
}
}

public static void SetConvarFlags(ushort convar, ulong flags){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.Push(flags);
ScriptContext.GlobalScriptContext.SetIdentifier(0xB2BDCCBF);
Copy link

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
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

ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static ulong GetConvarFlags(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0x94829E2B);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (ulong)ScriptContext.GlobalScriptContext.GetResult(typeof(ulong));
}
}

public static short GetConvarType(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0xB6E0E54C);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (short)ScriptContext.GlobalScriptContext.GetResult(typeof(short));
}
}

public static string GetConvarName(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0xB6F0E2F3);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
}
}

public static string GetConvarHelpText(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0x341D1F67);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
}
}

public static ushort GetConvarAccessIndexByName(string name){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(name);
ScriptContext.GlobalScriptContext.SetIdentifier(0x6288420D);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (ushort)ScriptContext.GlobalScriptContext.GetResult(typeof(ushort));
}
}

public static T GetConvarValue<T>(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0x935B2E9F);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (T)ScriptContext.GlobalScriptContext.GetResult(typeof(T));
}
}

public static string GetConvarValueAsString(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0x5CC184F8);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
}
}

public static void SetConvarValueAsString(ushort convar, string value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0x5EF52D6C);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static object SetConvarValue<T>(ushort convar, T value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0xB3DDAA0B);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (object)ScriptContext.GlobalScriptContext.GetResult(typeof(object));
}
}

public static ushort CreateConvar<T>(string name, short type, string helptext, ulong flags, bool hasmin, bool hasmax, T defaultvalue, T minvalue, T maxvalue){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(name);
ScriptContext.GlobalScriptContext.Push(type);
ScriptContext.GlobalScriptContext.Push(helptext);
ScriptContext.GlobalScriptContext.Push(flags);
ScriptContext.GlobalScriptContext.Push(hasmin);
ScriptContext.GlobalScriptContext.Push(hasmax);
ScriptContext.GlobalScriptContext.Push(defaultvalue);
ScriptContext.GlobalScriptContext.Push(minvalue);
ScriptContext.GlobalScriptContext.Push(maxvalue);
ScriptContext.GlobalScriptContext.SetIdentifier(0xF22079B9);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (ushort)ScriptContext.GlobalScriptContext.GetResult(typeof(ushort));
}
}

public static void DeleteConvar(ushort convar){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(convar);
ScriptContext.GlobalScriptContext.SetIdentifier(0xFC28F444);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static string GetStringFromSymbolLarge(IntPtr pointer){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
Expand Down
25 changes: 25 additions & 0 deletions managed/CounterStrikeSharp.API/Core/BasePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@
internal readonly Dictionary<Delegate, EntityIO.EntityOutputCallback> EntitySingleOutputHooks =
new Dictionary<Delegate, EntityIO.EntityOutputCallback>();

internal readonly List<ConVarBase> ConVars = [];

public readonly List<CommandDefinition> CommandDefinitions = new List<CommandDefinition>();

public readonly List<Timer> Timers = new List<Timer>();
Expand Down Expand Up @@ -367,6 +369,7 @@
this.RegisterAttributeHandlers(instance);
this.RegisterConsoleCommandAttributeHandlers(instance);
this.RegisterEntityOutputAttributeHandlers(instance);
this.RegisterConVars(instance);
this.RegisterFakeConVars(instance);
}

Expand Down Expand Up @@ -498,7 +501,7 @@
}
}

public void RegisterFakeConVars(Type type, object instance = null)

Check warning on line 504 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Cannot convert null literal to non-nullable reference type.

Check warning on line 504 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Cannot convert null literal to non-nullable reference type.
{
var convars = type
.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
Expand All @@ -524,6 +527,19 @@
});
}
}

public void RegisterConVars(Type type, object instance = null)

Check warning on line 531 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Cannot convert null literal to non-nullable reference type.

Check warning on line 531 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Cannot convert null literal to non-nullable reference type.
{
var convars = type
.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
.Where(prop => prop.FieldType.IsGenericType &&
prop.FieldType.GetGenericTypeDefinition() == typeof(ConVar<>));

foreach (var prop in convars)
{
ConVars.Add(prop.GetValue(instance) as ConVarBase); // ConVar<?> instance
}
}

/// <summary>
/// Used to bind a fake ConVar to a plugin command. Only required for ConVars that are not public properties of the plugin class.
Expand All @@ -535,6 +551,10 @@
RegisterFakeConVars(instance.GetType(), instance);
}

public void RegisterConVars(object instance) {
RegisterConVars(instance.GetType(), instance);
}

/// <summary>
/// Hooks an <a href="https://developer.valvesoftware.com/wiki/Inputs_and_Outputs">entity output</a>.
/// </summary>
Expand Down Expand Up @@ -657,6 +677,11 @@
subscriber.Dispose();
}

foreach (var convar in ConVars)
{
convar.Delete();
}

foreach (var definition in CommandDefinitions)
{
CommandManager.RemoveCommand(definition);
Expand Down
3 changes: 2 additions & 1 deletion managed/CounterStrikeSharp.API/Modules/Cvars/ConVar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace CounterStrikeSharp.API.Modules.Cvars;

[Obsolete("Use ConVar<T> instead for type-safe access to ConVars.")]
public class ConVar
{
public IntPtr Handle { get; }
Expand Down Expand Up @@ -127,7 +128,7 @@ public string StringValue
throw new InvalidOperationException(
$"ConVar is a {Type} but you are trying to get a string value.");
}

NativeAPI.SetConvarStringValue(Handle, value);
}
}
Expand Down
Loading
Loading