Compare commits

...

6 Commits

Author SHA1 Message Date
qstage
e99d27ca30 fix: errors when reloading auto generated config (#754) 2025-01-30 21:08:44 +10:00
dependabot[bot]
44d3c51bc7 [no ci] chore(deps): bump libraries/Protobufs from b46090a to 157162d (#753)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-30 11:22:36 +10:00
Joakim
f72e6d5daf feat: add ReplicateConVar (#751) 2025-01-27 22:10:14 +00:00
samyyc
c8bccb07e0 Remove the characters limit for CenterHtmlMenu (#747) 2025-01-23 13:06:06 +00:00
qstage
2c0640700a fix: ArgumentOutOfRangeException when calling GetArgTargetResult (#745) 2025-01-23 22:53:51 +10:00
Ian Lucas
0f71e1aebe feat: handle quotes for FakeConVar<string> (#743) 2025-01-20 12:09:44 +10:00
9 changed files with 72 additions and 42 deletions

View File

@@ -206,6 +206,18 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void ReplicateConvar(int clientslot, string convarname, string convarvalue){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(clientslot);
ScriptContext.GlobalScriptContext.Push(convarname);
ScriptContext.GlobalScriptContext.Push(convarvalue);
ScriptContext.GlobalScriptContext.SetIdentifier(0xC8728BEC);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static T DynamicHookGetReturn<T>(IntPtr hook, int datatype){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();

View File

@@ -347,4 +347,9 @@ public partial class CCSPlayerController
{
base.Teleport(position, angles, velocity);
}
public void ReplicateConVar(string conVar, string value)
{
NativeAPI.ReplicateConvar(Slot, conVar, value);
}
}

View File

@@ -36,7 +36,7 @@ public class Target
private static bool ConstTargetType(string target, out TargetType targetType)
{
targetType = TargetType.Invalid;
if (!target.StartsWith("@"))
if (!target.StartsWith('@'))
{
return false;
}
@@ -50,13 +50,13 @@ public class Target
{
targetType = TargetType.Invalid;
slug = null!;
if (!target.StartsWith("#"))
if (!target.StartsWith('#'))
{
return false;
}
slug = target.TrimStart('#');
if (slug.StartsWith("STEAM")) targetType = TargetType.IdSteamEscaped;
if (slug.StartsWith("STEAM") && slug.Contains(':')) targetType = TargetType.IdSteamEscaped;
else if (!ulong.TryParse(slug, out _)) targetType = TargetType.ExplicitName;
else if (slug.Length == 17) targetType = TargetType.IdSteam64;
else targetType = TargetType.IdUserid;
@@ -101,10 +101,9 @@ public class Target
TargetType.GroupNotMe => player.SteamID != caller?.SteamID,
TargetType.PlayerMe => player.SteamID == caller?.SteamID,
TargetType.IdUserid => player.UserId.ToString() == Slug,
TargetType.IdSteamEscaped => ((SteamID)player.SteamID).SteamId2 == Slug,
TargetType.IdSteam64 => ((SteamID)player.SteamID).SteamId64.ToString() == Slug,
TargetType.ExplicitName => player.PlayerName.Contains(Slug, StringComparison.OrdinalIgnoreCase),
TargetType.ImplicitName => player.PlayerName.Contains(Slug, StringComparison.OrdinalIgnoreCase),
TargetType.IdSteamEscaped when player.SteamID != 0 => (SteamID)player.SteamID == (SteamID)Slug,
TargetType.IdSteam64 => player.SteamID.ToString() == Slug,
TargetType.ExplicitName or TargetType.ImplicitName => player.PlayerName.Contains(Slug, StringComparison.OrdinalIgnoreCase),
_ => false
};
}

View File

@@ -72,6 +72,16 @@ public class FakeConVar<T> where T : IComparable<T>
try
{
var argString = args.ArgString;
if (typeof(T) == typeof(string))
{
if (argString.Length >= 2 && argString.StartsWith('"') && argString.EndsWith('"'))
{
argString = argString.Substring(1, argString.Length - 2);
}
}
// TODO(dotnet8): Replace with IParsable<T>
bool success = true;
T parsedValue = default(T);
@@ -80,11 +90,11 @@ public class FakeConVar<T> where T : IComparable<T>
{
try
{
parsedValue = (T)converter.ConvertFromString(args.ArgString);
parsedValue = (T)converter.ConvertFromString(argString);
}
catch
{
success = typeof(T) == typeof(bool) && TryConvertCustomBoolean(args.ArgString, out parsedValue);
success = typeof(T) == typeof(bool) && TryConvertCustomBoolean(argString, out parsedValue);
}
}
@@ -137,4 +147,4 @@ public class FakeConVar<T> where T : IComparable<T>
_value = value;
ValueChanged?.Invoke(this, _value);
}
}
}

View File

@@ -7,7 +7,8 @@ public static class PluginConfigExtensions
{
private static readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
WriteIndented = true
WriteIndented = true,
ReadCommentHandling = JsonCommentHandling.Skip
};
public static JsonSerializerOptions JsonSerializerOptions => _jsonSerializerOptions;
@@ -62,7 +63,7 @@ public static class PluginConfigExtensions
var configContent = File.ReadAllText(configPath);
var newConfig = JsonSerializer.Deserialize<T>(configContent)
var newConfig = JsonSerializer.Deserialize<T>(configContent, JsonSerializerOptions)
?? throw new JsonException($"Deserialization failed for configuration file '{configPath}'.");
foreach (var property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))

View File

@@ -29,13 +29,13 @@ public class CenterHtmlMenu : BaseMenu
public string NextPageColor { get; set; } = "yellow";
public string CloseColor { get; set; } = "red";
public CenterHtmlMenu(string title, BasePlugin plugin) : base(ModifyTitle(title))
public CenterHtmlMenu(string title, BasePlugin plugin) : base(title)
{
_plugin = plugin;
}
[Obsolete("Use the constructor that takes a BasePlugin")]
public CenterHtmlMenu(string title) : base(ModifyTitle(title))
public CenterHtmlMenu(string title) : base(title)
{
}
@@ -45,40 +45,18 @@ public class CenterHtmlMenu : BaseMenu
{
throw new InvalidOperationException("This method is unsupported with the CenterHtmlMenu constructor used." +
"Please provide a BasePlugin in the constructor.");
};
};
MenuManager.OpenCenterHtmlMenu(_plugin, player, this);
}
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect,
bool disabled = false)
{
var option = new ChatMenuOption(ModifyOptionDisplay(display), disabled, onSelect);
var option = new ChatMenuOption(display, disabled, onSelect);
MenuOptions.Add(option);
return option;
}
private static string ModifyTitle(string title)
{
if (title.Length > 32)
{
Application.Instance.Logger.LogWarning("Title should not be longer than 32 characters for a CenterHtmlMenu");
return title[..32];
}
return title;
}
private static string ModifyOptionDisplay(string display)
{
if (display.Length > 26)
{
Application.Instance.Logger.LogWarning("Display should not be longer than 26 characters for a CenterHtmlMenu item");
return display[..26];
}
return display;
}
}
public class CenterHtmlMenuInstance : BaseMenuInstance

View File

@@ -15,13 +15,17 @@
*/
#include <eiface.h>
#include <networksystem/inetworkmessages.h>
#include "scripting/autonative.h"
#include "scripting/callback_manager.h"
#include "core/managers/con_command_manager.h"
#include "core/managers/player_manager.h"
#include "core/recipientfilters.h"
#include "igameeventsystem.h"
#include "scripting/script_engine.h"
#include "core/log.h"
#include <networkbasetypes.pb.h>
namespace counterstrikesharp {
@@ -191,6 +195,25 @@ void SetConVarStringValue(ScriptContext& script_context)
pCvar->values = reinterpret_cast<CVValue_t**>((char*)value);
}
void ReplicateConVar(ScriptContext& script_context)
{
auto slot = script_context.GetArgument<int>(0);
auto name = script_context.GetArgument<const char*>(1);
auto value = script_context.GetArgument<const char*>(2);
INetworkMessageInternal* pNetMsg = globals::networkMessages->FindNetworkMessagePartial("SetConVar");
auto msg = pNetMsg->AllocateMessage()->ToPB<CNETMsg_SetConVar>();
CMsg_CVars_CVar* cvarMsg = msg->mutable_convars()->add_cvars();
cvarMsg->set_name(name);
cvarMsg->set_value(value);
CSingleRecipientFilter filter(slot);
globals::gameEventSystem->PostEventAbstract(-1, false, &filter, pNetMsg, msg, 0);
delete msg;
}
REGISTER_NATIVES(commands, {
ScriptEngine::RegisterNativeHandler("ADD_COMMAND", AddCommand);
ScriptEngine::RegisterNativeHandler("REMOVE_COMMAND", RemoveCommand);
@@ -211,5 +234,6 @@ REGISTER_NATIVES(commands, {
IssueClientCommandFromServer);
ScriptEngine::RegisterNativeHandler("GET_CLIENT_CONVAR_VALUE", GetClientConVarValue);
ScriptEngine::RegisterNativeHandler("SET_FAKE_CLIENT_CONVAR_VALUE", SetFakeClientConVarValue);
ScriptEngine::RegisterNativeHandler("REPLICATE_CONVAR", ReplicateConVar);
})
} // namespace counterstrikesharp

View File

@@ -12,4 +12,5 @@ ISSUE_CLIENT_COMMAND_FROM_SERVER: slot:int,command:string -> void
FIND_CONVAR: name:string -> pointer
SET_CONVAR_STRING_VALUE: convar:pointer,value:string -> void
GET_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string -> string
SET_FAKE_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string,convarValue:string -> void
SET_FAKE_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string,convarValue:string -> void
REPLICATE_CONVAR: clientSlot:int,convarName:string,convarValue:string -> void