namespace Aeshnidae.Towns; /// /// Allegiance towns (Tom, 2026-09-29: "build me buyable towns"): an allegiance pools pyreals in a /// treasury, its monarch buys a charter, and a town on the menu becomes that allegiance's own /// private copy - somewhere its members TRAVEL to with /town go (Tom, 2026-10-09), while the /// public town stays exactly as it was for everyone, owners included. See Towns.cs. The town /// machinery is InstancesNoDat's enclaves, bound by reflection (Instances.cs). Building on a town /// (a steward, a catalogue, the allegiance vault, hooks) comes next. /// public class Mod : IHarmonyMod { public static readonly string Name = typeof(Mod).Assembly.GetName().Name!; public static readonly string HarmonyId = $"mod.{Name.ToLowerInvariant()}"; public static readonly string ModPath = Path.Combine(ModManager.ModPath, Name); public static ModContainer? Container => ModManager.GetModContainerByPath(ModPath); public static Settings Settings { get; private set; } = new(); private static Harmony? _harmony; private bool _disposed; public void Initialize() { try { Settings = Settings.Load(ModPath); Towns.Load(); Instances.Refresh(); // binds, and registers every town _harmony = new Harmony(HarmonyId); // Explicit assembly: the parameterless overload walks the stack and can land on ACE.Server. _harmony.PatchAllUncategorized(typeof(Mod).Assembly); ModManager.Log($"[{Name}] loaded - {(Settings.Enabled ? "ON" : "off")}: {Towns.LoadStatus}; {Settings.Towns?.Count ?? 0} town(s) on the menu; charter {Settings.CharterPrice:N0}; binding {Instances.Status}; a copy is opt-in (/town go or a login inside; nothing routes anyone in)"); } catch (Exception ex) { ModManager.Log($"[{Name}] failed to start: {ex}", ModManager.LogLevel.Error); } } public static void ReloadSettings() { Towns.UnregisterAll(); Settings = Settings.Load(ModPath); Towns.Load(); if (Settings.Enabled && Instances.Refresh()) Towns.RegisterAll(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { // Towns come down with the mod: nobody is routed to a town nothing here can serve. try { Towns.UnregisterAll(); } catch { } Instances.Unbind(); _harmony?.UnpatchAll(HarmonyId); _harmony = null; ModManager.Log($"[{Name}] shut down"); } _disposed = true; } }