From 3da9472431516a2947e23882e00697acb296b364 Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:19:59 +0300 Subject: [PATCH 1/3] feat: command args feature --- .../Exiled.API/Features/Core/CommandArgs.cs | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 EXILED/Exiled.API/Features/Core/CommandArgs.cs diff --git a/EXILED/Exiled.API/Features/Core/CommandArgs.cs b/EXILED/Exiled.API/Features/Core/CommandArgs.cs new file mode 100644 index 0000000000..518ddb7a90 --- /dev/null +++ b/EXILED/Exiled.API/Features/Core/CommandArgs.cs @@ -0,0 +1,180 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +using System.Globalization; + +namespace Exiled.API.Features.Core +{ + using System; + using System.Linq; + using System.Text.RegularExpressions; + + /// + /// A helper class to easily access command arguments. + /// + public class CommandArgs + { + private readonly string[] args; + private readonly CultureInfo cultureInfo; + + /// + /// Initializes a new instance of the class. + /// + /// Parsed command arguments. + /// Current culture info. Used for float conversions. + internal CommandArgs(string[] args, CultureInfo cultureInfo) + { + this.args = args; + this.cultureInfo = cultureInfo; + } + + /// + /// Parses an instance of from an array of arguments. + /// + /// Array of arguments. + /// Whether the regex should be used. + /// to be used with float-pointing number conversions. + /// An instance of . + /// + /// Usage of allows to separate arguments not by space char, but also with quotes. + /// For example, command with structure + /// commandName one "two three" four + /// will be separated into + /// { "one", "two three", "four" } + /// + public static CommandArgs Parse(ArraySegment arguments, bool useRegex = false, CultureInfo cultureInfo = null) + { + if (!useRegex) + return new(arguments.Array, cultureInfo ?? CultureInfo.CurrentCulture); + + string[] result = Regex.Matches(string.Join(" ", arguments), @"""([^""]*)""|(\S+)") + .Select(m => m.Groups[1].Success ? m.Groups[1].Value : m.Value) + .ToArray(); + + return new(result, cultureInfo ?? CultureInfo.CurrentCulture); + } + + /// + /// Gets a value as an from specified position. + /// + /// Index of an argument. + /// Returned value or null. + public int GetInt(uint index) => GetValue(index); + + /// + /// Gets a value as a from specified position. + /// + /// Index of an argument. + /// Returned value or null. + public float GetFloat(uint index) => GetValue(index); + + /// + /// Gets a value as a from specified position. + /// + /// Index of an argument. + /// Returned value or null. + public Player GetPlayer(uint index) => Player.Get(GetString(index)); + + /// + /// Gets a value as a from specified position. + /// + /// Index of an argument. + /// Returned value or null. + public string GetString(uint index) + { + if (index >= args.Length) + return null; + + return args[index]; + } + + /// + /// Tries to get a value as an from specified position. + /// + /// Index of an argument. + /// Returned value. May be null. + /// true if succeeded. Otherwise, false. + public bool TryGetInt(uint index, out int result) => TryGetValue(index, out result); + + /// + /// Tries to get a value as an from specified position. + /// + /// Index of an argument. + /// Returned value. May be null. + /// true if succeeded. Otherwise, false. + public bool GetFloat(uint index, out float result) => TryGetValue(index, out result); + + /// + /// Tries to get a value as an from specified position. + /// + /// Index of an argument. + /// Returned value. May be null. + /// true if succeeded. Otherwise, false. + public bool TryGetPlayer(uint index, out Player result) => (result = GetPlayer(index)) != null; + + /// + /// Tries to get a value as an from specified position. + /// + /// Index of an argument. + /// Returned value. May be null. + /// true if succeeded. Otherwise, false. + public bool TryGetString(uint index, out string result) => (result = GetString(index)) != null; + + /// + /// Gets a value as a generic type. + /// + /// Index of a value. + /// Type of object to be casted to. + /// Casted value or null. + public T GetValue(uint index) + { + if (index >= args.Length) + return default(T); + + try + { + return (T)Convert.ChangeType(args[index], typeof(T), cultureInfo); + } + catch (InvalidCastException) + { + return default(T); + } + } + + /// + /// Gets a value as a generic type. + /// + /// Index of a value. + /// Casted value. + /// Type of object to be casted to. + /// true if value of specific type was successfully retrieved. Otherwise, false. + public bool TryGetValue(uint index, out T result) + { + result = default(T); + + if (index >= args.Length) + return false; + + object value; + + try + { + value = Convert.ChangeType(args[index], typeof(T), cultureInfo); + } + catch (InvalidCastException) + { + return false; + } + + if (value == null) + return false; + + result = (T)value; + return true; + } + } +} \ No newline at end of file From 4550134c0754bf798afe1c551b181e2b15aa5ca2 Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:29:49 +0300 Subject: [PATCH 2/3] fix: rename TryGetFloat --- EXILED/Exiled.API/Features/Core/CommandArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.API/Features/Core/CommandArgs.cs b/EXILED/Exiled.API/Features/Core/CommandArgs.cs index 518ddb7a90..1be7cd48ce 100644 --- a/EXILED/Exiled.API/Features/Core/CommandArgs.cs +++ b/EXILED/Exiled.API/Features/Core/CommandArgs.cs @@ -106,7 +106,7 @@ public string GetString(uint index) /// Index of an argument. /// Returned value. May be null. /// true if succeeded. Otherwise, false. - public bool GetFloat(uint index, out float result) => TryGetValue(index, out result); + public bool TryGetFloat(uint index, out float result) => TryGetValue(index, out result); /// /// Tries to get a value as an from specified position. From a687f5a7f458059ceb79598d04a9e3e4fdbbab55 Mon Sep 17 00:00:00 2001 From: "@Someone" <45270312+Someone-193@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:37:31 -0400 Subject: [PATCH 3/3] fix --- .../Exiled.API/Features/Core/CommandArgs.cs | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/EXILED/Exiled.API/Features/Core/CommandArgs.cs b/EXILED/Exiled.API/Features/Core/CommandArgs.cs index 1be7cd48ce..85ce818573 100644 --- a/EXILED/Exiled.API/Features/Core/CommandArgs.cs +++ b/EXILED/Exiled.API/Features/Core/CommandArgs.cs @@ -5,11 +5,10 @@ // // ----------------------------------------------------------------------- -using System.Globalization; - namespace Exiled.API.Features.Core { using System; + using System.Globalization; using System.Linq; using System.Text.RegularExpressions; @@ -40,22 +39,21 @@ internal CommandArgs(string[] args, CultureInfo cultureInfo) /// to be used with float-pointing number conversions. /// An instance of . /// - /// Usage of allows to separate arguments not by space char, but also with quotes. - /// For example, command with structure + /// Usage of allows to separate arguments not by space char, but also with quotes. For example, command with structure: /// commandName one "two three" four - /// will be separated into + /// will be separated into: /// { "one", "two three", "four" } /// public static CommandArgs Parse(ArraySegment arguments, bool useRegex = false, CultureInfo cultureInfo = null) { if (!useRegex) - return new(arguments.Array, cultureInfo ?? CultureInfo.CurrentCulture); + return new CommandArgs(arguments.Array, cultureInfo ?? CultureInfo.CurrentCulture); string[] result = Regex.Matches(string.Join(" ", arguments), @"""([^""]*)""|(\S+)") .Select(m => m.Groups[1].Success ? m.Groups[1].Value : m.Value) .ToArray(); - return new(result, cultureInfo ?? CultureInfo.CurrentCulture); + return new CommandArgs(result, cultureInfo ?? CultureInfo.CurrentCulture); } /// @@ -84,13 +82,7 @@ public static CommandArgs Parse(ArraySegment arguments, bool useRegex = /// /// Index of an argument. /// Returned value or null. - public string GetString(uint index) - { - if (index >= args.Length) - return null; - - return args[index]; - } + public string GetString(uint index) => index >= args.Length ? null : args[index]; /// /// Tries to get a value as an from specified position. @@ -128,7 +120,7 @@ public string GetString(uint index) /// Gets a value as a generic type. /// /// Index of a value. - /// Type of object to be casted to. + /// Type of object to be cast to. /// Casted value or null. public T GetValue(uint index) { @@ -150,7 +142,7 @@ public T GetValue(uint index) /// /// Index of a value. /// Casted value. - /// Type of object to be casted to. + /// Type of object to be cast to. /// true if value of specific type was successfully retrieved. Otherwise, false. public bool TryGetValue(uint index, out T result) {