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/2] 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/2] 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.