namespace Aeshnidae.Codex;
///
/// Read from Settings.json in the deployed mod folder; written with defaults on first
/// run. Nothing here touches the sections' content - each mod renders its own pages.
///
public class Settings
{
public const string FileName = "Settings.json";
///
/// The weenie the Codex is made from. 364 is retail's blank "Book": fifty pages of a
/// thousand characters, the writable kind vendors sold - so the client already
/// knows how to open it, page it and render it. Changing this to a book with fewer
/// pages truncates the Codex; the contents page says how many fit.
///
public uint BookWcid { get; set; } = 364;
/// What the book is called. Also how an existing one is recognised, so rename with care.
public string Name { get; set; } = "Aelrynth Codex";
/// The line under the title when the book is examined.
public string Inscription { get; set; } = "Everything the server knows about you, rewritten each time you open it.";
/// A dat icon id to use instead of the book's own. 0 keeps the book's icon.
public uint IconOverride { get; set; } = 0;
/// Hand a Codex to every character that enters the world without one.
public bool GrantOnLogin { get; set; } = true;
///
/// Characters per page. Retail parchment was 1,000 and the book window was built
/// for it; a page longer than the book's own MaxNumCharsPerPage is cut regardless.
///
public int MaxCharsPerPage { get; set; } = 1000;
///
/// The mods whose CodexPage is asked for pages, in book order. A mod that is off,
/// or has no CodexPage, is skipped. /codex sections shows which answer.
///
public string[] Sections { get; set; } =
{
"Aeshnidae.Bank",
"Aeshnidae.SkillMastery",
"Aeshnidae.ResonanceAuras",
"Aeshnidae.QuestBonus",
"Aeshnidae.Enlightenment",
"Aeshnidae.Leaderboard",
};
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true,
};
public static Settings Load(string modPath)
{
var path = Path.Combine(modPath, FileName);
try
{
if (File.Exists(path))
{
var loaded = JsonSerializer.Deserialize(File.ReadAllText(path), JsonOptions) ?? new Settings();
loaded.Sections ??= Array.Empty();
return loaded;
}
var defaults = new Settings();
defaults.Save(modPath);
ModManager.Log($"[{Mod.Name}] wrote default settings to {path}");
return defaults;
}
catch (Exception ex)
{
ModManager.Log($"[{Mod.Name}] could not read {path}, using defaults: {ex.Message}", ModManager.LogLevel.Warn);
return new Settings();
}
}
public void Save(string modPath)
{
try
{
File.WriteAllText(Path.Combine(modPath, FileName), JsonSerializer.Serialize(this, JsonOptions));
}
catch (Exception ex)
{
ModManager.Log($"[{Mod.Name}] could not save settings: {ex.Message}", ModManager.LogLevel.Error);
}
}
}