using System.Text.Json; using System.Text.Json.Serialization; namespace DNFLoadout; internal sealed class Config { public string ServerUrl { get; set; } = "http://127.0.0.1:18111"; public string AdminToken { get; set; } = ""; public List Pages { get; set; } = new(); public int ActivePage { get; set; } // Legacy pre-page format: keep the old JSON field readable, but never write it. [JsonPropertyName("Schemes")] public List? LegacySchemes { get; set; } [JsonIgnore] public LoadoutPage CurrentPage { get { Normalize(); return Pages[ActivePage]; } } public void Normalize() { if (Pages == null) Pages = new(); if (Pages.Count == 0 && LegacySchemes is { Count: > 0 }) Pages.Add(new LoadoutPage { Name = "默认页", Schemes = LegacySchemes }); LegacySchemes = null; if (Pages.Count == 0) Pages.Add(new LoadoutPage { Name = "默认页" }); ActivePage = Math.Clamp(ActivePage, 0, Pages.Count - 1); } } internal sealed class LoadoutPage { public string Name { get; set; } = "默认页"; public List Schemes { get; set; } = new(); } internal sealed class Scheme { public string Name { get; set; } = "方案"; public string CharacterName { get; set; } = ""; public int Modifiers { get; set; } public int KeyCode { get; set; } public List Slots { get; set; } = new(); [JsonIgnore] public string HotkeyText => HotkeyTextOf(Modifiers, KeyCode); [JsonIgnore] public string Display => $"{Name} [{CharacterName}] [{HotkeyText}] ({Slots.Count} 件)"; public static string HotkeyTextOf(int modifiers, int keyCode) { if (keyCode == 0) return "未设置"; var parts = new List(); if ((modifiers & 0x2) != 0) parts.Add("Ctrl"); if ((modifiers & 0x1) != 0) parts.Add("Alt"); if ((modifiers & 0x4) != 0) parts.Add("Shift"); var key = (Keys)keyCode; parts.Add(key.ToString()); return string.Join("+", parts); } } internal sealed class SlotItem { [JsonPropertyName("slot")] public int Slot { get; set; } [JsonPropertyName("item_id")] public long ItemId { get; set; } } internal sealed class ConfigStore { private static string PathFile { get { var portable = Path.Combine(AppContext.BaseDirectory, "config.json"); if (File.Exists(portable)) return portable; return Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DNFLoadout", "config.json"); } } public static Config Load() { try { if (File.Exists(PathFile)) { var json = File.ReadAllText(PathFile); var config = JsonSerializer.Deserialize(json) ?? new Config(); config.Normalize(); return config; } } catch { } var fresh = new Config(); fresh.Normalize(); return fresh; } public static void Save(Config config) { config.Normalize(); Directory.CreateDirectory(Path.GetDirectoryName(PathFile)!); File.WriteAllText(PathFile, JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, })); } }