Skip to content

Commit 288f41f

Browse files
committed
feat: add string manipulation
1 parent 003f255 commit 288f41f

File tree

5 files changed

+114
-9
lines changed

5 files changed

+114
-9
lines changed

managed/CounterStrikeSharp.API/Core/API.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,28 @@ public static T GetConvarValue<T>(ushort convar){
295295
}
296296
}
297297

298+
public static string GetConvarValueAsString(ushort convar){
299+
lock (ScriptContext.GlobalScriptContext.Lock) {
300+
ScriptContext.GlobalScriptContext.Reset();
301+
ScriptContext.GlobalScriptContext.Push(convar);
302+
ScriptContext.GlobalScriptContext.SetIdentifier(0x5CC184F8);
303+
ScriptContext.GlobalScriptContext.Invoke();
304+
ScriptContext.GlobalScriptContext.CheckErrors();
305+
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
306+
}
307+
}
308+
309+
public static void SetConvarValueAsString(ushort convar, string value){
310+
lock (ScriptContext.GlobalScriptContext.Lock) {
311+
ScriptContext.GlobalScriptContext.Reset();
312+
ScriptContext.GlobalScriptContext.Push(convar);
313+
ScriptContext.GlobalScriptContext.Push(value);
314+
ScriptContext.GlobalScriptContext.SetIdentifier(0x5EF52D6C);
315+
ScriptContext.GlobalScriptContext.Invoke();
316+
ScriptContext.GlobalScriptContext.CheckErrors();
317+
}
318+
}
319+
298320
public static object SetConvarValue<T>(ushort convar, T value){
299321
lock (ScriptContext.GlobalScriptContext.Lock) {
300322
ScriptContext.GlobalScriptContext.Reset();

managed/CounterStrikeSharp.API/Modules/Cvars/ConVarOfT.cs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System;
2-
using System.Runtime.CompilerServices;
3-
using CounterStrikeSharp.API.Core;
41
using CounterStrikeSharp.API.Modules.Utils;
52

63
namespace CounterStrikeSharp.API.Modules.Cvars;
@@ -25,7 +22,11 @@ public ConVar(ushort accessIndex)
2522
/// <summary>
2623
/// The ConVar flags as defined by <see cref="ConVarFlags"/>.
2724
/// </summary>
28-
public ConVarFlags Flags => (ConVarFlags)NativeAPI.GetConvarFlags(AccessIndex);
25+
public ConVarFlags Flags
26+
{
27+
get => (ConVarFlags)NativeAPI.GetConvarFlags(AccessIndex);
28+
set => NativeAPI.SetConvarFlags(AccessIndex, (ulong)value);
29+
}
2930

3031
public T Value
3132
{
@@ -104,11 +105,6 @@ public T Value
104105
throw new InvalidOperationException(
105106
$"ConVar is a {Type} but you are trying to get a {type} value.");
106107
break;
107-
case ConVarType.Color:
108-
if (type != typeof(Vector))
109-
throw new InvalidOperationException(
110-
$"ConVar is a {Type} but you are trying to get a {type} value.");
111-
break;
112108
default:
113109
throw new InvalidOperationException($"Unknown ConVar type: {Type}");
114110
}
@@ -118,6 +114,12 @@ public T Value
118114
set => NativeAPI.SetConvarValue(AccessIndex, value);
119115
}
120116

117+
public string ValueAsString
118+
{
119+
get => NativeAPI.GetConvarValueAsString(AccessIndex);
120+
set => NativeAPI.SetConvarValueAsString(AccessIndex, value);
121+
}
122+
121123
public static ConVar<T>? Find(string name)
122124
{
123125
var accessIndex = NativeAPI.GetConvarAccessIndexByName(name);
@@ -126,6 +128,30 @@ public T Value
126128
return new ConVar<T>(accessIndex);
127129
}
128130

131+
/// <summary>
132+
/// Shorthand for checking the <see cref="ConVarFlags.FCVAR_NOTIFY"/> flag.
133+
/// </summary>
134+
public bool Public
135+
{
136+
get => Flags.HasFlag(ConVarFlags.FCVAR_NOTIFY);
137+
set
138+
{
139+
if (value)
140+
{
141+
Flags |= ConVarFlags.FCVAR_NOTIFY;
142+
}
143+
else
144+
{
145+
Flags &= ~ConVarFlags.FCVAR_NOTIFY;
146+
}
147+
}
148+
}
149+
150+
public override string ToString()
151+
{
152+
return $"ConVar [name={Name}, value={Value}, description={Description}, type={Type}, flags={Flags}]";
153+
}
154+
129155
public sealed record ConVarCreationOptions
130156
{
131157
public required string Name { get; init; }

managed/CounterStrikeSharp.Tests.Native/ConVarTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ public void CreateFloatConVar()
193193
// Test min/max constraints
194194
conVar.Value = 50.0f;
195195
Assert.Equal(25.0f, conVar.Value);
196+
Assert.Equal("25.0", conVar.ValueAsString);
197+
198+
conVar.ValueAsString = "10.5";
199+
Assert.Equal(10.5f, conVar.Value);
196200

197201
conVar.Delete();
198202

src/scripting/natives/natives_convars.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,55 @@ static void GetConvarAccessIndexByName(ScriptContext& script_context)
118118
script_context.SetResult(ref.GetAccessIndex());
119119
}
120120

121+
static void GetConvarValueAsString(ScriptContext& script_context)
122+
{
123+
auto convarAccessIndex = script_context.GetArgument<uint16>(0);
124+
auto ref = ConVarRefAbstract(convarAccessIndex);
125+
CSplitScreenSlot server(0);
126+
127+
if (!ref.IsValidRef())
128+
{
129+
script_context.ThrowNativeError("Invalid convar access index.");
130+
return;
131+
}
132+
133+
if (!ref.IsConVarDataValid())
134+
{
135+
script_context.ThrowNativeError("Convar data is not valid for access index %d.", convarAccessIndex);
136+
return;
137+
}
138+
139+
CBufferString buf;
140+
ref.GetValueAsString(buf, server);
141+
script_context.SetResult(buf.Get());
142+
}
143+
144+
static void SetConvarValueAsString(ScriptContext& script_context)
145+
{
146+
auto convarAccessIndex = script_context.GetArgument<uint16>(0);
147+
auto ref = ConVarRefAbstract(convarAccessIndex);
148+
CSplitScreenSlot server(0);
149+
150+
if (!ref.IsValidRef())
151+
{
152+
script_context.ThrowNativeError("Invalid convar access index.");
153+
return;
154+
}
155+
156+
if (!ref.IsConVarDataValid())
157+
{
158+
script_context.ThrowNativeError("Convar data is not valid for access index %d.", convarAccessIndex);
159+
return;
160+
}
161+
162+
auto value = script_context.GetArgument<const char*>(1);
163+
if (!ref.SetString(value, server))
164+
{
165+
script_context.ThrowNativeError("Failed to set value for convar %s.", ref.GetName());
166+
return;
167+
}
168+
}
169+
121170
static void GetConvarValue(ScriptContext& script_context)
122171
{
123172
auto convarAccessIndex = script_context.GetArgument<uint16>(0);
@@ -462,6 +511,8 @@ REGISTER_NATIVES(convars, {
462511
ScriptEngine::RegisterNativeHandler("GET_CONVAR_HELP_TEXT", GetConvarHelpText);
463512
ScriptEngine::RegisterNativeHandler("GET_CONVAR_ACCESS_INDEX_BY_NAME", GetConvarAccessIndexByName);
464513
ScriptEngine::RegisterNativeHandler("GET_CONVAR_VALUE", GetConvarValue);
514+
ScriptEngine::RegisterNativeHandler("GET_CONVAR_VALUE_AS_STRING", GetConvarValueAsString);
515+
ScriptEngine::RegisterNativeHandler("SET_CONVAR_VALUE_AS_STRING", SetConvarValueAsString);
465516
ScriptEngine::RegisterNativeHandler("SET_CONVAR_VALUE", SetConvarValue);
466517
ScriptEngine::RegisterNativeHandler("CREATE_CONVAR", CreateConVar);
467518
ScriptEngine::RegisterNativeHandler("DELETE_CONVAR", DeleteConVar);

src/scripting/natives/natives_convars.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ GET_CONVAR_NAME: convar:uint16 -> string
55
GET_CONVAR_HELP_TEXT: convar:uint16 -> string
66
GET_CONVAR_ACCESS_INDEX_BY_NAME: name:string -> uint16
77
GET_CONVAR_VALUE: convar:uint16 -> any
8+
GET_CONVAR_VALUE_AS_STRING: convar:uint16 -> string
9+
SET_CONVAR_VALUE_AS_STRING: convar:uint16, value:string -> void
810
SET_CONVAR_VALUE: convar:uint16, value:any -> void\
911
CREATE_CONVAR: name:string, type:int16, helpText:string, flags:uint64, hasMin:bool, hasMax:bool, defaultValue:any, minValue:any, maxValue:any -> uint16
1012
DELETE_CONVAR: convar:uint16 -> void

0 commit comments

Comments
 (0)