From 2420e16fa40f61bd19c84cc2453fa8af1802419a Mon Sep 17 00:00:00 2001 From: That_One_Nerd Date: Wed, 19 Apr 2023 20:37:54 -0400 Subject: [PATCH] Made the config append system fully automated. --- .../Shell/Extensions/ConversionExtension.cs | 20 +++++++ SrcMod/Shell/GlobalUsings.cs | 1 + SrcMod/Shell/Modules/ConfigModule.cs | 55 ++++++++++--------- SrcMod/Shell/Shell.csproj | 4 ++ 4 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 SrcMod/Shell/Extensions/ConversionExtension.cs diff --git a/SrcMod/Shell/Extensions/ConversionExtension.cs b/SrcMod/Shell/Extensions/ConversionExtension.cs new file mode 100644 index 0000000..599c6ea --- /dev/null +++ b/SrcMod/Shell/Extensions/ConversionExtension.cs @@ -0,0 +1,20 @@ +namespace SrcMod.Shell.Extensions; + +public static class ConversionExtension +{ + public static T Cast(this object obj) => (T)Cast(obj, typeof(T)); + public static object Cast(this object obj, Type newType) => Convert.ChangeType(obj, newType); + + public static object CastArray(this object[] obj, Type newElementType) + { + Array result = Array.CreateInstance(newElementType, obj.Length); + for (int i = 0; i < obj.Length; i++) result.SetValue(obj[i].Cast(newElementType), i); + return result; + } + public static T[] CastArray(this object[] obj) + { + Array result = Array.CreateInstance(typeof(T), obj.Length); + for (int i = 0; i < obj.Length; i++) result.SetValue(obj[i].Cast(), i); + return (T[])result; + } +} diff --git a/SrcMod/Shell/GlobalUsings.cs b/SrcMod/Shell/GlobalUsings.cs index d5d9a6f..19bbcbb 100644 --- a/SrcMod/Shell/GlobalUsings.cs +++ b/SrcMod/Shell/GlobalUsings.cs @@ -3,6 +3,7 @@ global using Newtonsoft.Json; global using SharpCompress.Archives.Rar; global using SharpCompress.Archives.SevenZip; global using SharpCompress.Readers; +global using SrcMod.Shell.Extensions; global using SrcMod.Shell.Interop; global using SrcMod.Shell.Modules.ObjectModels; global using SrcMod.Shell.ObjectModels; diff --git a/SrcMod/Shell/Modules/ConfigModule.cs b/SrcMod/Shell/Modules/ConfigModule.cs index 0977a3e..cea4cba 100644 --- a/SrcMod/Shell/Modules/ConfigModule.cs +++ b/SrcMod/Shell/Modules/ConfigModule.cs @@ -29,21 +29,30 @@ public static class ConfigModule [Command("append")] public static void AppendConfigVariable(string name, string value) { - Config config = Config.LoadedConfig; + FieldInfo[] validFields = (from field in typeof(Config).GetFields() + let isPublic = field.IsPublic + let isStatic = field.IsStatic + where isPublic && !isStatic + select field).ToArray(); - switch (name.Trim().ToLower()) - { - case "gamedirectories": - config.GameDirectories = config.GameDirectories.Append(value).ToArray(); - break; + FieldInfo? chosenField = validFields.FirstOrDefault(x => x.Name.Trim().ToLower() == name.Trim().ToLower()); + if (chosenField is null) throw new($"No valid config variable named \"{name}\"."); + else if (!chosenField.FieldType.IsArray) throw new($"The variable \"{chosenField.Name}\" is not an array" + + " and cannot have data added or removed from it." + + " Instead, set or reset the variable."); - case "rununsafecommands": - throw new($"The config variable \"{name}\" is a single variable and cannot be appended to."); + object parsed = TypeParsers.ParseAll(value); + if (parsed is string parsedStr + && chosenField.FieldType.IsEnum + && Enum.TryParse(chosenField.FieldType, parsedStr, true, out object? obj)) parsed = obj; - default: throw new($"Unknown config variable \"{name}\""); - } + Type arrayType = chosenField.FieldType.GetElementType()!; - Config.LoadedConfig = config; + Array arrayValue = (Array)chosenField.GetValue(Config.LoadedConfig)!; + ArrayList collection = new(arrayValue) { parsed }; + + chosenField.SetValue(Config.LoadedConfig, collection.ToArray()!.CastArray(arrayType)); + DisplayConfigItem(chosenField.GetValue(Config.LoadedConfig), name: chosenField.Name); } [Command("delete")] @@ -96,8 +105,9 @@ public static class ConfigModule FieldInfo? chosenField = validFields.FirstOrDefault(x => x.Name.Trim().ToLower() == name.Trim().ToLower()); if (chosenField is null) throw new($"No valid config variable named \"{name}\"."); - else if (chosenField.FieldType.IsArray) throw new($"The variable \"{name}\" is an array and cannot be" + - " directly set. Instead, add or remove items from it."); + else if (chosenField.FieldType.IsArray) throw new($"The variable \"{chosenField.Name}\" is an array and" + + " cannot be directly set. Instead, add or remove items" + + " from it."); object parsed = TypeParsers.ParseAll(value); if (parsed is string parsedStr @@ -124,27 +134,20 @@ public static class ConfigModule Write(new string(' ', indents * 4), newLine: false); if (!string.IsNullOrWhiteSpace(name)) Write($"{name}: ", newLine: false); - if (item is IEnumerable itemEnumerable) + if (item is null) Write("null", ConsoleColor.DarkRed, newLine); + else if (item is Array itemArray) { - // This is a bit inefficient. - int count = 0; - foreach (object _ in itemEnumerable) count++; - - object[] itemData = new object[count]; - count = 0; - foreach (object obj in itemEnumerable) itemData[count] = obj; - - if (itemData.Length < 1) + if (itemArray.Length < 1) { Write("[]", ConsoleColor.DarkGray, newLine); return; } Write("[", ConsoleColor.DarkGray); - for (int i = 0; i < itemData.Length; i++) + for (int i = 0; i < itemArray.Length; i++) { - DisplayConfigItem(itemData.GetValue(i), indents + 1, newLine: false); - if (i < itemData.Length - 1) Write(',', newLine: false); + DisplayConfigItem(itemArray.GetValue(i), indents + 1, newLine: false); + if (i < itemArray.Length - 1) Write(',', newLine: false); Write('\n', newLine: false); } Write(new string(' ', indents * 4) + "]", ConsoleColor.DarkGray, newLine); diff --git a/SrcMod/Shell/Shell.csproj b/SrcMod/Shell/Shell.csproj index 253835f..804ac4f 100644 --- a/SrcMod/Shell/Shell.csproj +++ b/SrcMod/Shell/Shell.csproj @@ -36,4 +36,8 @@ + + + +