namespace Aeshnidae.OverworldCopies; /// Settings.json beside the dll. public class Settings { public const string FileName = "Settings.json"; /// /// The switch. /overworld on and /overworld off flip it and write it back here, so /// it survives a restart. Off: no bubble exists, /overworld enter refuses, and every /// patch passes straight through to ACE and InstancesNoDat. /// public bool Enabled { get; set; } = false; /// /// Lowest access level for /overworld enter, join and leave: 0 Player ... 5 Admin. /// The switch itself, list and close are always Admin. /// public int EnterAccessLevel { get; set; } = 0; /// /// Housing is left out of every bubble: a house, its slumlord, storage, hooks and /// portal exist once, with one owner and contents saved against their guid, so a /// second copy of them would be a second copy of someone's house. By WeenieType name. /// public List LeftOutTypes { get; set; } = ["House", "SlumLord", "Storage", "Hook", "HousePortal", "BootSpot", "Deed", "AllegianceBindstone"]; /// Log each enter, exit and edge crossing. public bool Trace { get; set; } = true; /// /// Where /overworld send puts players in a region: region name -> "0xCELL x y z qw qz". /// The Aerlinthe ones are the retail Aerlinthe Island Portal's landing (7413), on the /// south shore in BAE8. The region itself (its landblocks, solo or group, variants) is /// InstancesNoDat's Outdoor entry. /// public Dictionary Landings { get; set; } = new(StringComparer.OrdinalIgnoreCase) { ["aerlinthe-south"] = "0xBAE8001D 84 105 26 0 -1", ["aerlinthe"] = "0xBAE8001D 84 105 26 0 -1", }; private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true, ReadCommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, PropertyNameCaseInsensitive = true, }; public static Settings Load(string modPath) { var path = Path.Combine(modPath, FileName); try { if (File.Exists(path)) return JsonSerializer.Deserialize(File.ReadAllText(path), JsonOptions) ?? new Settings(); var defaults = new Settings(); defaults.Save(modPath); return defaults; } catch (Exception ex) { ModManager.Log($"[{Mod.Name}] could not read {path}, using defaults (switched off): {ex.Message}", ModManager.LogLevel.Warn); return new Settings(); } } public void Save(string modPath) { var path = Path.Combine(modPath, FileName); try { var tmp = path + ".tmp"; File.WriteAllText(tmp, JsonSerializer.Serialize(this, JsonOptions)); File.Move(tmp, path, true); } catch (Exception ex) { ModManager.Log($"[{Mod.Name}] could not write {path}: {ex.Message}", ModManager.LogLevel.Warn); } } }