From fef548b22ba2ef6e8a514bfabd31203cf171c41b Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 14:10:14 +0200 Subject: [PATCH 01/18] Add Config --- src/Managers/Config.cs | 120 +++++++++++++++++++++++++++++++++++++++++ src/PolyScriptMod.cs | 23 ++++++++ 2 files changed, 143 insertions(+) create mode 100644 src/Managers/Config.cs create mode 100644 src/PolyScriptMod.cs diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs new file mode 100644 index 0000000..f213c11 --- /dev/null +++ b/src/Managers/Config.cs @@ -0,0 +1,120 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace PolyMod.Managers; + +/// +/// allows mods to save config. +/// +public class Config where T : class +{ + private T? _currentConfig; + private readonly string _modName; + private readonly ConfigTypes _configType; + private static readonly string ExposedConfigPath = Path.Combine(Plugin.BASE_PATH, "mods.json"); + private readonly string _perModConfigPath; + private T? _defaultConfig; + public Config(string modName, ConfigTypes configType) + { + _modName = modName; + _configType = configType; + _perModConfigPath = Path.Combine(Plugin.MODS_PATH, $"{modName}.json"); + Load(); + } + + internal void Load() // can be called internally if config changes; gui config not implemented yet + { + switch (_configType) + { + case ConfigTypes.PerMod: + { + if (!File.Exists(_perModConfigPath)) + { + return; + } + var jsonText = File.ReadAllText(_perModConfigPath); + _currentConfig = JsonConvert.DeserializeObject(jsonText); + break; + } + case ConfigTypes.Exposed: + { + if (!File.Exists(ExposedConfigPath)) + { + return; + } + var jsonText = File.ReadAllText(ExposedConfigPath); + _currentConfig = JObject.Parse(jsonText)[_modName].ToObject(); + break; + } + default: + throw new ArgumentOutOfRangeException(); + } + } + /// + /// Sets the default if the config does not exist yet. Always call this before reading from the config. + /// + public void SetDefaultConfig(T defaultValue) + { + _defaultConfig = defaultValue; + if (_currentConfig is not null) return; + Write(_defaultConfig); + SaveChanges(); + } + + /// + /// Writes the **entire** config. Usage not recommended, use Edit() instead + /// + public void Write(T config) + { + _currentConfig = config; + } + /// + /// Gets the config. Should only be called after setting a default. + /// + public T Get() + { + return _currentConfig ?? throw new InvalidOperationException("Must set default before reading config."); + } + /// + /// edits the config. Should only be called after setting a default. + /// + /// Call SaveChanges after editing + public void Edit(Action editor) + { + editor(_currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); + } + /// + /// Gets part of the config. Should only be called after setting a default + /// + public TResult Get(Func getter) + { + return getter(_currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); + } + /// + /// writes the config to disk + /// + public void SaveChanges() + { + switch (_configType) + { + case ConfigTypes.PerMod: + var json = JsonConvert.SerializeObject(_currentConfig, Formatting.Indented); + File.WriteAllText(_perModConfigPath, json); + break; + case ConfigTypes.Exposed: + var modsConfigText = File.ReadAllText(ExposedConfigPath); + var modsConfigJson = JObject.Parse(modsConfigText); + modsConfigJson[_modName] = JToken.FromObject(_currentConfig); + File.WriteAllText(ExposedConfigPath, modsConfigJson.ToString(Formatting.Indented)); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public enum ConfigTypes + { + PerMod, + Exposed + } +} \ No newline at end of file diff --git a/src/PolyScriptMod.cs b/src/PolyScriptMod.cs new file mode 100644 index 0000000..7c1782d --- /dev/null +++ b/src/PolyScriptMod.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json.Linq; +using PolyMod.Managers; + +namespace PolyMod; + +public abstract class PolyScriptMod where TConfig : class where TExposedConfig : class +{ + internal void Initialize(string name) + { + ModName = name; + Config = new Config(name, Config.ConfigTypes.PerMod); + ExposedConfig = new Config(name, Config.ConfigTypes.Exposed); + } + public string ModName { get; private set; } + protected Config Config { get; private set; } = null!; + protected Config ExposedConfig { get; private set; } = null!; + protected virtual JObject DefaultConfig => new JObject(); + public abstract void OnLoad(); +} + +public abstract class PolyScriptMod : PolyScriptMod +{ +} \ No newline at end of file From dc3a10f1bf35afb9fcecb5d20866c6c146223d68 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 15:04:05 +0200 Subject: [PATCH 02/18] Actually load the mod # Conflicts: # src/Loader.cs --- src/Loader.cs | 19 ++++++++++++++++--- src/PolyScriptMod.cs | 14 +++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Loader.cs b/src/Loader.cs index f218f14..b333748 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -279,8 +279,7 @@ internal static void LoadMods(Dictionary mods) files.Add(new(entry.FullName, entry.ReadBytes())); } } - - // Validate manifest + #region ValidateManifest() if (manifest == null) { Plugin.logger.LogError($"Mod manifest not found in {modContainer}"); @@ -311,6 +310,7 @@ internal static void LoadMods(Dictionary mods) Plugin.logger.LogError($"Mod {manifest.id} already exists"); continue; } + #endregion mods.Add(manifest.id, new( manifest, Mod.Status.Success, @@ -319,7 +319,11 @@ internal static void LoadMods(Dictionary mods) Plugin.logger.LogInfo($"Registered mod {manifest.id}"); } - // Check dependencies + CheckDependencies(mods); + } + + private static void CheckDependencies(Dictionary mods) + { foreach (var (id, mod) in mods) { foreach (var dependency in mod.dependencies ?? Array.Empty()) @@ -431,6 +435,15 @@ public static void LoadAssemblyFile(Mod mod, Mod.File file) try { Assembly assembly = Assembly.Load(file.bytes); + if (assembly + .GetTypes() + .FirstOrDefault(t => t.IsSubclassOf(typeof(PolyScriptModBase))) + is { } modType) + { + var modInstance = (PolyScriptModBase) Activator.CreateInstance(modType)!; + modInstance.Initialize(mod.id); + modInstance.Load(); + } foreach (Type type in assembly.GetTypes()) { MethodInfo? loadWithLogger = type.GetMethod("Load", new Type[] { typeof(ManualLogSource) }); diff --git a/src/PolyScriptMod.cs b/src/PolyScriptMod.cs index 7c1782d..fe9ba3f 100644 --- a/src/PolyScriptMod.cs +++ b/src/PolyScriptMod.cs @@ -3,9 +3,18 @@ namespace PolyMod; -public abstract class PolyScriptMod where TConfig : class where TExposedConfig : class +public abstract class PolyScriptModBase { - internal void Initialize(string name) + internal abstract void Initialize(string name); + public abstract void Load(); + public abstract void UnLoad(); + internal PolyScriptModBase() + { + } +} +public abstract class PolyScriptMod : PolyScriptModBase where TConfig : class where TExposedConfig : class +{ + internal override void Initialize(string name) { ModName = name; Config = new Config(name, Config.ConfigTypes.PerMod); @@ -15,7 +24,6 @@ internal void Initialize(string name) protected Config Config { get; private set; } = null!; protected Config ExposedConfig { get; private set; } = null!; protected virtual JObject DefaultConfig => new JObject(); - public abstract void OnLoad(); } public abstract class PolyScriptMod : PolyScriptMod From 5e8328bf0af020bf9ed3db01cf265399cf0656ed Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 16:07:26 +0200 Subject: [PATCH 03/18] Slight refactor and fix of warning --- resources/localization.json | 2 +- src/Loader.cs | 34 ++++++++++++++++++++++++++++++++-- src/Managers/Config.cs | 4 ++-- src/Managers/Main.cs | 28 +--------------------------- 4 files changed, 36 insertions(+), 32 deletions(-) diff --git a/resources/localization.json b/resources/localization.json index e9afd56..068d435 100644 --- a/resources/localization.json +++ b/resources/localization.json @@ -22,7 +22,7 @@ "German (Germany)": "UNSER DISCORD" }, "polymod_hub_footer": { - "English": "Join our discord! Feel free to discuss mods, create them and ask for help!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "English": "Join our discord! Feel free to discuss mods, create them and ask for help!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", "Russian": "Присоединяйтесь к нашему дискорду! Не стесняйтесь обсуждать моды, создавать их и просить о помощи!\n\n{0}Особая благодарность{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", "Turkish": "Discord sunucumuza katıl! Orada modlar oluşturabilir, tartışabilir ve yardım isteyebilirsin!\n\n{0}Hepinize çok teşekkür ederim:{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", "Spanish (Mexico)": "Unete a nuestro discord! Aqui se puede discutir sobre la modificacion del juego, guias para crear su propio, preguntar a los creadores, y mas!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", diff --git a/src/Loader.cs b/src/Loader.cs index b333748..c9cb762 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -230,7 +230,7 @@ public static void AddPatchDataType(string typeId, Type type, bool shouldCreateC /// Loads all mods from the mods directory. /// /// A dictionary to populate with the loaded mods. - internal static void LoadMods(Dictionary mods) + internal static void RegisterMods(Dictionary mods) { Directory.CreateDirectory(Plugin.MODS_PATH); string[] modContainers = Directory.GetDirectories(Plugin.MODS_PATH) @@ -322,6 +322,36 @@ internal static void LoadMods(Dictionary mods) CheckDependencies(mods); } + internal static void LoadMods(Dictionary mods) + { + var dependencyCycle = !SortMods(Registry.mods); + if (dependencyCycle) return; + + StringBuilder checksumString = new(); + foreach (var (id, mod) in Registry.mods) + { + if (mod.status != Mod.Status.Success) continue; + foreach (var file in mod.files) + { + checksumString.Append(JsonSerializer.Serialize(file)); + if (Path.GetExtension(file.name) == ".dll") + { + LoadAssemblyFile(mod, file); + } + if (Path.GetFileName(file.name) == "sprites.json") + { + LoadSpriteInfoFile(mod, file); + } + } + if (!mod.client && id != "polytopia") + { + checksumString.Append(id); + checksumString.Append(mod.version.ToString()); + } + } + Compatibility.HashSignatures(checksumString); + + } private static void CheckDependencies(Dictionary mods) { foreach (var (id, mod) in mods) @@ -366,7 +396,7 @@ private static void CheckDependencies(Dictionary mods) /// /// The dictionary of mods to sort. /// True if the mods could be sorted (no circular dependencies), false otherwise. - internal static bool SortMods(Dictionary mods) + private static bool SortMods(Dictionary mods) { Stopwatch s = new(); Dictionary> graph = new(); diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index f213c11..c4b164a 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -43,7 +43,7 @@ public Config(string modName, ConfigTypes configType) return; } var jsonText = File.ReadAllText(ExposedConfigPath); - _currentConfig = JObject.Parse(jsonText)[_modName].ToObject(); + _currentConfig = JObject.Parse(jsonText)[_modName]!.ToObject(); break; } default: @@ -104,7 +104,7 @@ public void SaveChanges() case ConfigTypes.Exposed: var modsConfigText = File.ReadAllText(ExposedConfigPath); var modsConfigJson = JObject.Parse(modsConfigText); - modsConfigJson[_modName] = JToken.FromObject(_currentConfig); + modsConfigJson[_modName] = JToken.FromObject(_currentConfig!); File.WriteAllText(ExposedConfigPath, modsConfigJson.ToString(Formatting.Indented)); break; default: diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index b9e19f4..1fab434 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -350,34 +350,8 @@ internal static void Init() Array.Empty() ); Registry.mods.Add(polytopia.id, new(polytopia, Mod.Status.Success, new())); + Loader.RegisterMods(Registry.mods); Loader.LoadMods(Registry.mods); - dependencyCycle = !Loader.SortMods(Registry.mods); - if (dependencyCycle) return; - - StringBuilder checksumString = new(); - foreach (var (id, mod) in Registry.mods) - { - if (mod.status != Mod.Status.Success) continue; - foreach (var file in mod.files) - { - checksumString.Append(JsonSerializer.Serialize(file)); - if (Path.GetExtension(file.name) == ".dll") - { - Loader.LoadAssemblyFile(mod, file); - } - if (Path.GetFileName(file.name) == "sprites.json") - { - Loader.LoadSpriteInfoFile(mod, file); - } - } - if (!mod.client && id != "polytopia") - { - checksumString.Append(id); - checksumString.Append(mod.version.ToString()); - } - } - Compatibility.HashSignatures(checksumString); - stopwatch.Stop(); } From 442a47fd2666370bb19ddfe5fd14f0794087861b Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 17:04:51 +0200 Subject: [PATCH 04/18] Use System.Text.json instead of newtonsoft --- src/Loader.cs | 2 +- src/Managers/Config.cs | 18 +++++++++--------- src/PolyScriptMod.cs | 8 +++++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Loader.cs b/src/Loader.cs index c9cb762..9c804d1 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -471,7 +471,7 @@ public static void LoadAssemblyFile(Mod mod, Mod.File file) is { } modType) { var modInstance = (PolyScriptModBase) Activator.CreateInstance(modType)!; - modInstance.Initialize(mod.id); + modInstance.Initialize(mod.id, BepInEx.Logging.Logger.CreateLogSource($"PolyMod] [{mod.id}")); modInstance.Load(); } foreach (Type type in assembly.GetTypes()) diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index c4b164a..e7efcbd 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; namespace PolyMod.Managers; @@ -33,7 +33,7 @@ public Config(string modName, ConfigTypes configType) return; } var jsonText = File.ReadAllText(_perModConfigPath); - _currentConfig = JsonConvert.DeserializeObject(jsonText); + _currentConfig = JsonSerializer.Deserialize(jsonText); break; } case ConfigTypes.Exposed: @@ -43,7 +43,7 @@ public Config(string modName, ConfigTypes configType) return; } var jsonText = File.ReadAllText(ExposedConfigPath); - _currentConfig = JObject.Parse(jsonText)[_modName]!.ToObject(); + _currentConfig = JsonNode.Parse(jsonText)![_modName]!.Deserialize(); break; } default: @@ -98,14 +98,14 @@ public void SaveChanges() switch (_configType) { case ConfigTypes.PerMod: - var json = JsonConvert.SerializeObject(_currentConfig, Formatting.Indented); - File.WriteAllText(_perModConfigPath, json); + var perModJson = JsonSerializer.Serialize(_currentConfig, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllText(_perModConfigPath, perModJson); break; case ConfigTypes.Exposed: var modsConfigText = File.ReadAllText(ExposedConfigPath); - var modsConfigJson = JObject.Parse(modsConfigText); - modsConfigJson[_modName] = JToken.FromObject(_currentConfig!); - File.WriteAllText(ExposedConfigPath, modsConfigJson.ToString(Formatting.Indented)); + var modsConfigJson = JsonNode.Parse(modsConfigText)!.AsObject(); + modsConfigJson[_modName] = JsonSerializer.SerializeToNode(_currentConfig!); + File.WriteAllText(ExposedConfigPath, modsConfigJson.ToJsonString(new JsonSerializerOptions { WriteIndented = true })); break; default: throw new ArgumentOutOfRangeException(); diff --git a/src/PolyScriptMod.cs b/src/PolyScriptMod.cs index fe9ba3f..b116767 100644 --- a/src/PolyScriptMod.cs +++ b/src/PolyScriptMod.cs @@ -1,3 +1,4 @@ +using BepInEx.Logging; using Newtonsoft.Json.Linq; using PolyMod.Managers; @@ -5,7 +6,7 @@ namespace PolyMod; public abstract class PolyScriptModBase { - internal abstract void Initialize(string name); + internal abstract void Initialize(string name, ManualLogSource logger); public abstract void Load(); public abstract void UnLoad(); internal PolyScriptModBase() @@ -14,16 +15,17 @@ internal PolyScriptModBase() } public abstract class PolyScriptMod : PolyScriptModBase where TConfig : class where TExposedConfig : class { - internal override void Initialize(string name) + internal override void Initialize(string name, ManualLogSource logger) { ModName = name; Config = new Config(name, Config.ConfigTypes.PerMod); ExposedConfig = new Config(name, Config.ConfigTypes.Exposed); + Logger = logger; } public string ModName { get; private set; } protected Config Config { get; private set; } = null!; protected Config ExposedConfig { get; private set; } = null!; - protected virtual JObject DefaultConfig => new JObject(); + protected ManualLogSource Logger { get; private set; } = null!; } public abstract class PolyScriptMod : PolyScriptMod From 782ff77a2972ec6ff9176f6cdf49263a25a4c097 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 17:28:14 +0200 Subject: [PATCH 05/18] add missing using statement --- src/Loader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Loader.cs b/src/Loader.cs index 9c804d1..d11e0a8 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -12,6 +12,7 @@ using System.Globalization; using System.IO.Compression; using System.Reflection; +using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using UnityEngine; From 0a90f234c3037266c2f6196693f2ac235ff43407 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 17:39:46 +0200 Subject: [PATCH 06/18] Fix 2 warnings --- src/PolyScriptMod.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PolyScriptMod.cs b/src/PolyScriptMod.cs index b116767..08fdd80 100644 --- a/src/PolyScriptMod.cs +++ b/src/PolyScriptMod.cs @@ -22,7 +22,8 @@ internal override void Initialize(string name, ManualLogSource logger) ExposedConfig = new Config(name, Config.ConfigTypes.Exposed); Logger = logger; } - public string ModName { get; private set; } + + public string ModName { get; private set; } = null!; protected Config Config { get; private set; } = null!; protected Config ExposedConfig { get; private set; } = null!; protected ManualLogSource Logger { get; private set; } = null!; From a5d4c2e9b8c7796f6660b8f9d90e38ec0323cbf8 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 19:49:19 +0200 Subject: [PATCH 07/18] Fix bug of game crashing on assembly load... --- src/Loader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Loader.cs b/src/Loader.cs index d11e0a8..ef07a92 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -474,6 +474,7 @@ public static void LoadAssemblyFile(Mod mod, Mod.File file) var modInstance = (PolyScriptModBase) Activator.CreateInstance(modType)!; modInstance.Initialize(mod.id, BepInEx.Logging.Logger.CreateLogSource($"PolyMod] [{mod.id}")); modInstance.Load(); + return; } foreach (Type type in assembly.GetTypes()) { From e8181eb3fee8e5d9a52a7ccfadf34284ed96feca Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 19:53:52 +0200 Subject: [PATCH 08/18] other languages in localization --- resources/localization.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/localization.json b/resources/localization.json index 068d435..c74653e 100644 --- a/resources/localization.json +++ b/resources/localization.json @@ -23,14 +23,14 @@ }, "polymod_hub_footer": { "English": "Join our discord! Feel free to discuss mods, create them and ask for help!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "Russian": "Присоединяйтесь к нашему дискорду! Не стесняйтесь обсуждать моды, создавать их и просить о помощи!\n\n{0}Особая благодарность{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "Turkish": "Discord sunucumuza katıl! Orada modlar oluşturabilir, tartışabilir ve yardım isteyebilirsin!\n\n{0}Hepinize çok teşekkür ederim:{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "Spanish (Mexico)": "Unete a nuestro discord! Aqui se puede discutir sobre la modificacion del juego, guias para crear su propio, preguntar a los creadores, y mas!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "French (France)": "Rejoignez notre discord! N'hésitez pas à discuter des mods, à en créer et à demander de l'aide!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "Polish": "Dołącz do naszego discorda! Zachęcamy do omawiania modów, tworzenia ich lub proszenia o pomoc!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "Portuguese (Brazil)": "Entre no nosso Discord! Sinta-se à vontade para discutir sobre os mods, criar novos mods e pedir ajuda!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "Elyrion": "§ii∫ Δi^#ȱrΔ! Δi^#₺^^ mȱΔ#, ȱrrȱ ỹ a^š ỹȱπ!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", - "German (Germany)": "Tritt unserem Discord bei, um Hilfe zu bekommen, Mods zu diskutieren oder sogar selbst zu erstellen!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon" + "Russian": "Присоединяйтесь к нашему дискорду! Не стесняйтесь обсуждать моды, создавать их и просить о помощи!\n\n{0}Особая благодарность{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "Turkish": "Discord sunucumuza katıl! Orada modlar oluşturabilir, tartışabilir ve yardım isteyebilirsin!\n\n{0}Hepinize çok teşekkür ederim:{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "Spanish (Mexico)": "Unete a nuestro discord! Aqui se puede discutir sobre la modificacion del juego, guias para crear su propio, preguntar a los creadores, y mas!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "French (France)": "Rejoignez notre discord! N'hésitez pas à discuter des mods, à en créer et à demander de l'aide!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "Polish": "Dołącz do naszego discorda! Zachęcamy do omawiania modów, tworzenia ich lub proszenia o pomoc!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "Portuguese (Brazil)": "Entre no nosso Discord! Sinta-se à vontade para discutir sobre os mods, criar novos mods e pedir ajuda!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "Elyrion": "§ii∫ Δi^#ȱrΔ! Δi^#₺^^ mȱΔ#, ȱrrȱ ỹ a^š ỹȱπ!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon", + "German (Germany)": "Tritt unserem Discord bei, um Hilfe zu bekommen, Mods zu diskutieren oder sogar selbst zu erstellen!\n\n{0}Special thanks{1}\n___exploit___\njohnklipi\nhighflyer\nMRB\nincomplete_tree\nArtemis\nParanoia\nNyrrv\nCitillan\nLukasAyas\nVaM\nWhail\nBrober\nMaradon" }, "polymod_hub_header": { "English": "{0}Welcome!{1}\nHere you can see the list of all currently loaded mods:", From fcc0da721c99f8053c91f2c6463a9bffd6356d23 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 19:58:31 +0200 Subject: [PATCH 09/18] rename polyscriptmod to polymod --- src/Managers/Config.cs | 4 ++-- src/{PolyScriptMod.cs => PolyMod.cs} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/{PolyScriptMod.cs => PolyMod.cs} (82%) diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index e7efcbd..981388a 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -4,7 +4,7 @@ namespace PolyMod.Managers; /// -/// allows mods to save config. +/// Allows mods to save config. /// public class Config where T : class { @@ -91,7 +91,7 @@ public TResult Get(Func getter) return getter(_currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); } /// - /// writes the config to disk + /// Writes the config to disk /// public void SaveChanges() { diff --git a/src/PolyScriptMod.cs b/src/PolyMod.cs similarity index 82% rename from src/PolyScriptMod.cs rename to src/PolyMod.cs index 08fdd80..77c2a6c 100644 --- a/src/PolyScriptMod.cs +++ b/src/PolyMod.cs @@ -13,7 +13,7 @@ internal PolyScriptModBase() { } } -public abstract class PolyScriptMod : PolyScriptModBase where TConfig : class where TExposedConfig : class +public abstract class PolyMod : PolyScriptModBase where TConfig : class where TExposedConfig : class { internal override void Initialize(string name, ManualLogSource logger) { @@ -29,6 +29,6 @@ internal override void Initialize(string name, ManualLogSource logger) protected ManualLogSource Logger { get; private set; } = null!; } -public abstract class PolyScriptMod : PolyScriptMod +public abstract class PolyMod : PolyMod { } \ No newline at end of file From 9ceb5bcedd11e784e4ef50d941ce96895fa2e472 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 18:36:25 +0200 Subject: [PATCH 10/18] Add gld config --- PolyMod.csproj | 3 +- src/Managers/Config.cs | 2 +- src/Managers/GLDConfig.cs | 84 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/Managers/GLDConfig.cs diff --git a/PolyMod.csproj b/PolyMod.csproj index 072a080..921dbba 100644 --- a/PolyMod.csproj +++ b/PolyMod.csproj @@ -1,4 +1,4 @@ - + net6.0 enable @@ -20,6 +20,7 @@ + diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index 981388a..371da03 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -43,7 +43,7 @@ public Config(string modName, ConfigTypes configType) return; } var jsonText = File.ReadAllText(ExposedConfigPath); - _currentConfig = JsonNode.Parse(jsonText)![_modName]!.Deserialize(); + _currentConfig = JsonNode.Parse(jsonText)![_modName]?.Deserialize(); break; } default: diff --git a/src/Managers/GLDConfig.cs b/src/Managers/GLDConfig.cs new file mode 100644 index 0000000..2dcdc30 --- /dev/null +++ b/src/Managers/GLDConfig.cs @@ -0,0 +1,84 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Scriban; +using Scriban.Runtime; + +namespace PolyMod.Managers; + +public class GldConfigTemplate +{ + private static readonly string ConfigPath = Path.Combine(Plugin.BASE_PATH, "mods.json"); + + private readonly string _templateText; + private JsonObject _currentConfig = new(); + private string _modName; + + public GldConfigTemplate(string templateText, string modName) + { + _templateText = templateText; + _modName = modName; + Load(); + } + private void Load() + { + if (File.Exists(ConfigPath)) + { + var json = File.ReadAllText(ConfigPath); + if (JsonNode.Parse(json) is JsonObject modsConfig + && modsConfig.TryGetPropertyValue(_modName, out var modConfigNode) + && modConfigNode is JsonObject modConfig) + { + _currentConfig = modConfig; + return; + } + } + _currentConfig = new JsonObject(); + } + + public string Render() + { + var template = Template.Parse(_templateText); + var context = new TemplateContext(); + var scriptObject = new ScriptObject(); + + bool changedConfig = false; + scriptObject.Import("config", + new Func((key, defaultValue) => + { + if (_currentConfig.TryGetPropertyValue(key, out var token) && token != null) + { + return token.ToString(); + } + + changedConfig = true; + _currentConfig[key] = defaultValue; + + return defaultValue; + }) + ); + context.PushGlobal(scriptObject); + var result = template.Render(context); + if (changedConfig) + { + SaveChanges(); + } + return result; + } + + public void SaveChanges() + { + JsonObject modsConfigJson; + if (File.Exists(ConfigPath)) + { + var modsConfigText = File.ReadAllText(ConfigPath); + modsConfigJson = (JsonNode.Parse(modsConfigText) as JsonObject) ?? new JsonObject(); + } + else + { + modsConfigJson = new JsonObject(); + } + + modsConfigJson[_modName] = _currentConfig; + File.WriteAllText(ConfigPath, modsConfigJson.ToJsonString(new JsonSerializerOptions { WriteIndented = true })); + } +} \ No newline at end of file From 2b34285556f174a8ae799c20f3d207bc8841649c Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 18:42:38 +0200 Subject: [PATCH 11/18] Actually load config --- src/Managers/GLDConfig.cs | 1 + src/Managers/Main.cs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Managers/GLDConfig.cs b/src/Managers/GLDConfig.cs index 2dcdc30..a8f287d 100644 --- a/src/Managers/GLDConfig.cs +++ b/src/Managers/GLDConfig.cs @@ -37,6 +37,7 @@ private void Load() public string Render() { + if (!_templateText.Contains("{{")) return _templateText; var template = Template.Parse(_templateText); var context = new TemplateContext(); var scriptObject = new ScriptObject(); diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index 1fab434..54134b3 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -382,10 +382,12 @@ internal static void Load(GameLogicData gameLogicData, JObject json) } if (Regex.IsMatch(Path.GetFileName(file.name), @"^patch(_.*)?\.json$")) { + var patchText = new StreamReader(new MemoryStream(file.bytes)).ReadToEnd(); + var template = new GldConfigTemplate(patchText, mod.id); Loader.LoadGameLogicDataPatch( mod, json, - JObject.Parse(new StreamReader(new MemoryStream(file.bytes)).ReadToEnd()) + JObject.Parse(template.Render()) ); continue; } From af3fcf2fa777dedee03676cecc94c346425291b6 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 18 Aug 2025 20:42:38 +0200 Subject: [PATCH 12/18] Revert "rename polyscriptmod to polymod" This reverts commit c5154ec21b0fe82487a17acec41dbd318e9d0bf4. --- src/Managers/Config.cs | 4 ++-- src/{PolyMod.cs => PolyScriptMod.cs} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/{PolyMod.cs => PolyScriptMod.cs} (82%) diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index 371da03..ca4264e 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -4,7 +4,7 @@ namespace PolyMod.Managers; /// -/// Allows mods to save config. +/// allows mods to save config. /// public class Config where T : class { @@ -91,7 +91,7 @@ public TResult Get(Func getter) return getter(_currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); } /// - /// Writes the config to disk + /// writes the config to disk /// public void SaveChanges() { diff --git a/src/PolyMod.cs b/src/PolyScriptMod.cs similarity index 82% rename from src/PolyMod.cs rename to src/PolyScriptMod.cs index 77c2a6c..08fdd80 100644 --- a/src/PolyMod.cs +++ b/src/PolyScriptMod.cs @@ -13,7 +13,7 @@ internal PolyScriptModBase() { } } -public abstract class PolyMod : PolyScriptModBase where TConfig : class where TExposedConfig : class +public abstract class PolyScriptMod : PolyScriptModBase where TConfig : class where TExposedConfig : class { internal override void Initialize(string name, ManualLogSource logger) { @@ -29,6 +29,6 @@ internal override void Initialize(string name, ManualLogSource logger) protected ManualLogSource Logger { get; private set; } = null!; } -public abstract class PolyMod : PolyMod +public abstract class PolyScriptMod : PolyScriptMod { } \ No newline at end of file From 7a60848ba6536d20d0fe8923beb7905d256fc0f8 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Tue, 19 Aug 2025 09:14:41 +0200 Subject: [PATCH 13/18] Fix bug related to game crashing on launch --- FodyWeavers.xml | 8 ++++++++ PolyMod.csproj | 3 +++ src/Managers/GLDConfig.cs | 13 +++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 FodyWeavers.xml diff --git a/FodyWeavers.xml b/FodyWeavers.xml new file mode 100644 index 0000000..d24cbce --- /dev/null +++ b/FodyWeavers.xml @@ -0,0 +1,8 @@ + + + + + Scriban + + + \ No newline at end of file diff --git a/PolyMod.csproj b/PolyMod.csproj index 921dbba..5a2e73a 100644 --- a/PolyMod.csproj +++ b/PolyMod.csproj @@ -20,6 +20,9 @@ + + all + diff --git a/src/Managers/GLDConfig.cs b/src/Managers/GLDConfig.cs index a8f287d..846332a 100644 --- a/src/Managers/GLDConfig.cs +++ b/src/Managers/GLDConfig.cs @@ -35,7 +35,7 @@ private void Load() _currentConfig = new JsonObject(); } - public string Render() + public string? Render() { if (!_templateText.Contains("{{")) return _templateText; var template = Template.Parse(_templateText); @@ -58,7 +58,16 @@ public string Render() }) ); context.PushGlobal(scriptObject); - var result = template.Render(context); + string? result; + try + { + result = template.Render(context); + } + catch (Exception e) + { + Plugin.logger.LogError("error during parse of gld patch template: " + e.ToString()); + result = null; + } if (changedConfig) { SaveChanges(); From 9e4827b2c072495d29a8f28e4ffcd794290cfc5f Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Tue, 19 Aug 2025 09:18:33 +0200 Subject: [PATCH 14/18] On error, set mod to errrror instead of crashing --- src/Managers/Main.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index 54134b3..95307a1 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -384,10 +384,16 @@ internal static void Load(GameLogicData gameLogicData, JObject json) { var patchText = new StreamReader(new MemoryStream(file.bytes)).ReadToEnd(); var template = new GldConfigTemplate(patchText, mod.id); + var text = template.Render(); + if (text is null) + { + mod.status = Mod.Status.Error; + continue; + } Loader.LoadGameLogicDataPatch( mod, json, - JObject.Parse(template.Render()) + JObject.Parse(text) ); continue; } From b8c98893463c9e29875327c36c63934597009320 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Tue, 19 Aug 2025 09:59:41 +0200 Subject: [PATCH 15/18] Change naming for @jkdev --- src/Managers/Config.cs | 50 +++++++++++++++++++-------------------- src/Managers/GLDConfig.cs | 26 ++++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index ca4264e..dddb15d 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -8,32 +8,32 @@ namespace PolyMod.Managers; /// public class Config where T : class { - private T? _currentConfig; - private readonly string _modName; - private readonly ConfigTypes _configType; + private T? currentConfig; + private readonly string modName; + private readonly ConfigTypes configType; private static readonly string ExposedConfigPath = Path.Combine(Plugin.BASE_PATH, "mods.json"); - private readonly string _perModConfigPath; - private T? _defaultConfig; + private readonly string perModConfigPath; + private T? defaultConfig; public Config(string modName, ConfigTypes configType) { - _modName = modName; - _configType = configType; - _perModConfigPath = Path.Combine(Plugin.MODS_PATH, $"{modName}.json"); + this.modName = modName; + this.configType = configType; + perModConfigPath = Path.Combine(Plugin.MODS_PATH, $"{modName}.json"); Load(); } internal void Load() // can be called internally if config changes; gui config not implemented yet { - switch (_configType) + switch (configType) { case ConfigTypes.PerMod: { - if (!File.Exists(_perModConfigPath)) + if (!File.Exists(perModConfigPath)) { return; } - var jsonText = File.ReadAllText(_perModConfigPath); - _currentConfig = JsonSerializer.Deserialize(jsonText); + var jsonText = File.ReadAllText(perModConfigPath); + currentConfig = JsonSerializer.Deserialize(jsonText); break; } case ConfigTypes.Exposed: @@ -43,7 +43,7 @@ public Config(string modName, ConfigTypes configType) return; } var jsonText = File.ReadAllText(ExposedConfigPath); - _currentConfig = JsonNode.Parse(jsonText)![_modName]?.Deserialize(); + currentConfig = JsonNode.Parse(jsonText)![modName]?.Deserialize(); break; } default: @@ -55,9 +55,9 @@ public Config(string modName, ConfigTypes configType) /// public void SetDefaultConfig(T defaultValue) { - _defaultConfig = defaultValue; - if (_currentConfig is not null) return; - Write(_defaultConfig); + defaultConfig = defaultValue; + if (currentConfig is not null) return; + Write(defaultConfig); SaveChanges(); } @@ -66,45 +66,45 @@ public void SetDefaultConfig(T defaultValue) /// public void Write(T config) { - _currentConfig = config; + currentConfig = config; } /// /// Gets the config. Should only be called after setting a default. /// public T Get() { - return _currentConfig ?? throw new InvalidOperationException("Must set default before reading config."); + return currentConfig ?? throw new InvalidOperationException("Must set default before reading config."); } /// - /// edits the config. Should only be called after setting a default. + /// Edits the config. Should only be called after setting a default. /// /// Call SaveChanges after editing public void Edit(Action editor) { - editor(_currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); + editor(currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); } /// /// Gets part of the config. Should only be called after setting a default /// public TResult Get(Func getter) { - return getter(_currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); + return getter(currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); } /// /// writes the config to disk /// public void SaveChanges() { - switch (_configType) + switch (configType) { case ConfigTypes.PerMod: - var perModJson = JsonSerializer.Serialize(_currentConfig, new JsonSerializerOptions { WriteIndented = true }); - File.WriteAllText(_perModConfigPath, perModJson); + var perModJson = JsonSerializer.Serialize(currentConfig, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllText(perModConfigPath, perModJson); break; case ConfigTypes.Exposed: var modsConfigText = File.ReadAllText(ExposedConfigPath); var modsConfigJson = JsonNode.Parse(modsConfigText)!.AsObject(); - modsConfigJson[_modName] = JsonSerializer.SerializeToNode(_currentConfig!); + modsConfigJson[modName] = JsonSerializer.SerializeToNode(currentConfig!); File.WriteAllText(ExposedConfigPath, modsConfigJson.ToJsonString(new JsonSerializerOptions { WriteIndented = true })); break; default: diff --git a/src/Managers/GLDConfig.cs b/src/Managers/GLDConfig.cs index 846332a..e341ab5 100644 --- a/src/Managers/GLDConfig.cs +++ b/src/Managers/GLDConfig.cs @@ -9,14 +9,14 @@ public class GldConfigTemplate { private static readonly string ConfigPath = Path.Combine(Plugin.BASE_PATH, "mods.json"); - private readonly string _templateText; - private JsonObject _currentConfig = new(); - private string _modName; + private readonly string templateText; + private JsonObject currentConfig = new(); + private string modName; public GldConfigTemplate(string templateText, string modName) { - _templateText = templateText; - _modName = modName; + this.templateText = templateText; + this.modName = modName; Load(); } private void Load() @@ -25,20 +25,20 @@ private void Load() { var json = File.ReadAllText(ConfigPath); if (JsonNode.Parse(json) is JsonObject modsConfig - && modsConfig.TryGetPropertyValue(_modName, out var modConfigNode) + && modsConfig.TryGetPropertyValue(modName, out var modConfigNode) && modConfigNode is JsonObject modConfig) { - _currentConfig = modConfig; + currentConfig = modConfig; return; } } - _currentConfig = new JsonObject(); + currentConfig = new JsonObject(); } public string? Render() { - if (!_templateText.Contains("{{")) return _templateText; - var template = Template.Parse(_templateText); + if (!templateText.Contains("{{")) return templateText; + var template = Template.Parse(templateText); var context = new TemplateContext(); var scriptObject = new ScriptObject(); @@ -46,13 +46,13 @@ private void Load() scriptObject.Import("config", new Func((key, defaultValue) => { - if (_currentConfig.TryGetPropertyValue(key, out var token) && token != null) + if (currentConfig.TryGetPropertyValue(key, out var token) && token != null) { return token.ToString(); } changedConfig = true; - _currentConfig[key] = defaultValue; + currentConfig[key] = defaultValue; return defaultValue; }) @@ -88,7 +88,7 @@ public void SaveChanges() modsConfigJson = new JsonObject(); } - modsConfigJson[_modName] = _currentConfig; + modsConfigJson[modName] = currentConfig; File.WriteAllText(ConfigPath, modsConfigJson.ToJsonString(new JsonSerializerOptions { WriteIndented = true })); } } \ No newline at end of file From 1788148daaeeaedb79a95b5ea3f729aed39baebb Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 8 Sep 2025 17:10:19 +0200 Subject: [PATCH 16/18] change name of polyScriptMod to PolyScript --- src/Loader.cs | 4 ++-- src/PolyScriptMod.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Loader.cs b/src/Loader.cs index ef07a92..8f48af4 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -468,10 +468,10 @@ public static void LoadAssemblyFile(Mod mod, Mod.File file) Assembly assembly = Assembly.Load(file.bytes); if (assembly .GetTypes() - .FirstOrDefault(t => t.IsSubclassOf(typeof(PolyScriptModBase))) + .FirstOrDefault(t => t.IsSubclassOf(typeof(PolyScriptBase))) is { } modType) { - var modInstance = (PolyScriptModBase) Activator.CreateInstance(modType)!; + var modInstance = (PolyScriptBase) Activator.CreateInstance(modType)!; modInstance.Initialize(mod.id, BepInEx.Logging.Logger.CreateLogSource($"PolyMod] [{mod.id}")); modInstance.Load(); return; diff --git a/src/PolyScriptMod.cs b/src/PolyScriptMod.cs index 08fdd80..d6975ce 100644 --- a/src/PolyScriptMod.cs +++ b/src/PolyScriptMod.cs @@ -4,16 +4,16 @@ namespace PolyMod; -public abstract class PolyScriptModBase +public abstract class PolyScriptBase { internal abstract void Initialize(string name, ManualLogSource logger); public abstract void Load(); public abstract void UnLoad(); - internal PolyScriptModBase() + internal PolyScriptBase() { } } -public abstract class PolyScriptMod : PolyScriptModBase where TConfig : class where TExposedConfig : class +public abstract class PolyScript : PolyScriptBase where TConfig : class where TExposedConfig : class { internal override void Initialize(string name, ManualLogSource logger) { @@ -29,6 +29,6 @@ internal override void Initialize(string name, ManualLogSource logger) protected ManualLogSource Logger { get; private set; } = null!; } -public abstract class PolyScriptMod : PolyScriptMod +public abstract class PolyScript : PolyScript { } \ No newline at end of file From 9260014873e89452f5178e0c6755c7721cfb9f44 Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 8 Sep 2025 17:50:20 +0200 Subject: [PATCH 17/18] fix --- src/Managers/Config.cs | 4 ++-- src/Managers/Main.cs | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Managers/Config.cs b/src/Managers/Config.cs index dddb15d..f320264 100644 --- a/src/Managers/Config.cs +++ b/src/Managers/Config.cs @@ -4,7 +4,7 @@ namespace PolyMod.Managers; /// -/// allows mods to save config. +/// Allows mods to save config. /// public class Config where T : class { @@ -91,7 +91,7 @@ public TResult Get(Func getter) return getter(currentConfig ?? throw new InvalidOperationException("Must set default before reading config.")); } /// - /// writes the config to disk + /// Writes the config to disk /// public void SaveChanges() { diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index 95307a1..7e416a6 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -32,12 +32,7 @@ public static class Main /// Whether the mod has been fully initialized. /// internal static bool fullyInitialized; - - /// - /// Whether a dependency cycle was detected among the loaded mods. - /// - internal static bool dependencyCycle; - + /// /// A dictionary mapping unit IDs to the IDs of the units they embark into. /// From 7a51f79b36cabc7768bbafda13868749daf21e2a Mon Sep 17 00:00:00 2001 From: Jouke van Dam Date: Mon, 8 Sep 2025 18:01:45 +0200 Subject: [PATCH 18/18] minor fix --- src/Loader.cs | 4 ++-- src/Managers/Main.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Loader.cs b/src/Loader.cs index 8f48af4..6bdc07e 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -323,9 +323,9 @@ internal static void RegisterMods(Dictionary mods) CheckDependencies(mods); } - internal static void LoadMods(Dictionary mods) + internal static void LoadMods(Dictionary mods, out bool dependencyCycle) { - var dependencyCycle = !SortMods(Registry.mods); + dependencyCycle = !SortMods(Registry.mods); if (dependencyCycle) return; StringBuilder checksumString = new(); diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index 7e416a6..37a06f8 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -18,6 +18,8 @@ namespace PolyMod.Managers; /// public static class Main { + internal static bool dependencyCycle; + /// /// The maximum tier for technology, used to extend the tech tree. /// @@ -346,7 +348,8 @@ internal static void Init() ); Registry.mods.Add(polytopia.id, new(polytopia, Mod.Status.Success, new())); Loader.RegisterMods(Registry.mods); - Loader.LoadMods(Registry.mods); + Loader.LoadMods(Registry.mods, out var cycle); + dependencyCycle = cycle; stopwatch.Stop(); }