using System; using System.IO; using System.Text.Json; using JXHelper.Common; using JXHelper.Core; namespace JXHelper.Config; /// /// Cấu hình hoạt động SSoT của JXHelper. /// Tuân thủ bất biến: INV-CONFIG-INI-SSOT. /// public class BotConfig { // ========================================================= // PHÂN HỆ PHỤC HỒI (RECOVERY - TAB P.HỒI THEO CHUẨN VLBS) // ========================================================= public bool HpPump1Enabled { get; set; } = true; public int HpPump1Key { get; set; } = 0x31; // Phím 1 public int HpPump1DelayMs { get; set; } = 1200; public bool HpPump2Enabled { get; set; } = false; public int HpPump2Key { get; set; } = 0x32; // Phím 2 public int HpPump2DelayMs { get; set; } = 2000; public bool MpPump1Enabled { get; set; } = true; public int MpPump1Key { get; set; } = 0x33; // Phím 3 public int MpPump1DelayMs { get; set; } = 1500; public bool MpPump2Enabled { get; set; } = false; public int MpPump2Key { get; set; } = 0x34; // Phím 4 public int MpPump2DelayMs { get; set; } = 2500; // Phân hệ Túi Máu Tân Thủ (Học hỏi & Chuẩn Auto Kim Yến) public bool AutoNewbiePouchEnabled { get; set; } = true; public int NewbiePouchIntervalSeconds { get; set; } = 60; // Chu kỳ mở túi (giây, mặc định 60s) public int NewbiePouchItemX { get; set; } = 575; // Tọa độ ô túi máu trong F4 public int NewbiePouchItemY { get; set; } = 345; public string NewbiePouchMenuSequence { get; set; } = "1,1"; // Phím 1 nhận thuốc, phím 1 xác nhận public string NewbiePouchPotionName { get; set; } = "Ngũ Hoa Ngọc Lộ Hoàn"; public int NewbiePouchEmergencyHpPercent { get; set; } = 65; // Kích hoạt khẩn cấp khi HP < 65% public bool AlarmOnTdp { get; set; } = true; // Rung chuông khi TDP // ========================================================= // PHÂN HỆ LUYỆN CÔNG (COMBAT - TAB L.CÔNG THEO CHUẨN VLBS) // ========================================================= public bool AutoAttackEnabled { get; set; } = true; public int AttackIntervalMs { get; set; } = 1000; public int AttackMode { get; set; } = 0; // 0: Chuột phải, 1: Chuột trái public int AttackRadius { get; set; } = 0; // 0: Đứng yên, 200: Gần, 400: Vừa, 800: Toàn màn hình public bool LockCurrentSpot { get; set; } = true; // Khóa bãi đứng (không di chuyển khỏi bãi Nghiệt Long Động 7x) public bool FollowLeaderEnabled { get; set; } = false; // Theo sau đội trưởng public bool AutoFollowCrossMap { get; set; } = true; // Tự động Thần Hành Phù bay theo khi khác Map (Chuẩn Kim Yến) public bool AutoHorseEnabled { get; set; } = true; // Phím M lên/xuống ngựa public bool AutoLootEnabled { get; set; } = true; // Spacebar nhặt đồ // 3 Slot Chiêu Buff Hỗ Trợ Độc Lập public bool Buff1Enabled { get; set; } = false; public int Buff1Key { get; set; } = 0x70; // F1 public int Buff1IntervalSeconds { get; set; } = 60; public string Buff1SkillName { get; set; } = string.Empty; public bool Buff2Enabled { get; set; } = false; public int Buff2Key { get; set; } = 0x71; // F2 public int Buff2IntervalSeconds { get; set; } = 120; public string Buff2SkillName { get; set; } = string.Empty; public bool Buff3Enabled { get; set; } = false; public int Buff3Key { get; set; } = 0x72; // F3 public int Buff3IntervalSeconds { get; set; } = 300; public string Buff3SkillName { get; set; } = string.Empty; // Chiêu đánh chính và Môn phái public string MainAttackSkillName { get; set; } = string.Empty; public string DetectedSect { get; set; } = string.Empty; // Gán chiêu thức mặc định khi bắt đầu (Chuẩn AutoVLBS: Trái / Phải) public bool AssignLeftSkillEnabled { get; set; } = false; public string DefaultLeftSkillName { get; set; } = string.Empty; public bool AssignRightSkillEnabled { get; set; } = false; public string DefaultRightSkillName { get; set; } = string.Empty; // ========================================================= // PHÂN HỆ NGA MY CHUYÊN BIỆT (TỪ HÀNG PHỔ ĐỘ & LƯU THỦY - MỘNG ĐIỆP) // ========================================================= public bool NgaMyHealEnabled { get; set; } = false; // Bơm Từ Hàng Phổ Độ public int NgaMyHealHpPercent { get; set; } = 70; // Sinh lực (%) public int NgaMyHealDelayMs { get; set; } = 2000; // Giãn cách bơm (ms) public bool NgaMyHealParty { get; set; } = true; // Bơm cho cả nhóm public bool NgaMySupportComboEnabled { get; set; } = false; // Hỗ trợ combo public int NgaMySupportComboMode { get; set; } = 0; // 0: "Lưu thuỷ - Mộng điệp", 1: "Phật Tâm Từ Hữu - Lưu thuỷ", 2: "Phật Tâm Từ Hữu - Mộng điệp" public int NgaMySupportIntervalSec { get; set; } = 90; // ========================================================= // PHÂN HỆ CHIÊU THỨC LUÂN CHUYỂN & BÙA CHÚ NGŨ ĐỘC (CHUẨN AUTO KIM YẾN) // ========================================================= public bool CurseRotationEnabled { get; set; } = false; public int CurseTriggerMode { get; set; } = 0; // 0: T.Gian (ms), 1: S.Lực (%), 2: N.Lực (%) public bool Curse1Enabled { get; set; } = false; // Chiêu thức #4 public string Curse1SkillName { get; set; } = string.Empty; public int Curse1IntervalMs { get; set; } = 5000; // mili giây public bool Curse2Enabled { get; set; } = false; // Chiêu thức #5 public string Curse2SkillName { get; set; } = string.Empty; public int Curse2IntervalMs { get; set; } = 8000; // mili giây // Phân hệ Buff bùa Ngũ Độc chuyên sâu (Chuẩn Auto Kim Yến) public bool NguDocCurseChainEnabled { get; set; } = false; // Bật chuỗi bùa tự động trước khi đánh public bool NguDocBossOnly { get; set; } = false; // Chỉ bùa Boss Xanh / Boss Vàng / Tinh Anh public bool NguDocCurseUHon { get; set; } = true; // Bùa U Hồn Phệ Phách (giảm tốc / giảm kháng) public bool NguDocCurseVanCo { get; set; } = true; // Bùa Vạn Cổ Thực Tâm (rút máu độc / giảm kháng độc) public bool NguDocCurseThiDoc { get; set; } = true; // Bùa Thi Độc Hủ Nhục (ăn mòn giáp / suy yếu) public bool NguDocCurseHoaCot { get; set; } = false; // Bùa Hóa Cốt Miên Chưởng (hút sinh lực) public int NguDocCurseDelayMs { get; set; } = 250; // Khoảng cách giữa các bùa (ms) public int NguDocCurseDurationSec { get; set; } = 15; // Thời gian hiệu lực bùa trước khi bùa lại (giây) public bool AutoBuffEnabled { get; set; } = false; // Backward compatibility public string BuffKeys { get; set; } = "F1,F2"; public int BuffIntervalSeconds { get; set; } = 60; // ========================================================= // PHÂN HỆ ĐIỀU KHIỂN & TIỆN ÍCH (CONTROL - TAB Đ.KHIỂN) // ========================================================= public bool AutoPartyEnabled { get; set; } = false; // Tự động nhận lời mời tổ đội (Ctrl+P) public bool IsPartyLeader { get; set; } = false; // Là chủ PT, chủ động mời các thành viên public string PartyMembers { get; set; } = "BoCuaCacCon,MeCuaCacCon,ConGailCung"; // Danh sách thành viên mời vào nhóm public string LeaderName { get; set; } = "ConCuaBoMe"; // Tên đội trưởng để đi theo public int FollowDistance { get; set; } = 100; // Khoảng cách theo sau (px, chuẩn AutoVLBS) public bool AutoTtlEnabled { get; set; } = false; // Tự dùng Tiên Thảo Lộ (x2 EXP) public int TtlIntervalMinutes { get; set; } = 60; public int TtlItemX { get; set; } = 575; public int TtlItemY { get; set; } = 320; public long LastTtlUseTimestamp { get; set; } = 0; public bool ScheduledShutdownEnabled { get; set; } = false; // Hẹn giờ tắt máy public int ShutdownMinutes { get; set; } = 120; public bool ScheduledExitGameEnabled { get; set; } = false; // Hẹn giờ thoát game public int ExitGameMinutes { get; set; } = 120; // ========================================================= // PHÂN HỆ TỌA ĐỘ & TUẦN TRA (PATROL - TAB T.ĐỘ) // ========================================================= public bool PatrolEnabled { get; set; } = false; // Tuần tra theo lộ trình public string WaypointsData { get; set; } = string.Empty; // "X1,Y1;X2,Y2" public int PatrolIntervalSeconds { get; set; } = 6; // ========================================================= // HẬU CẦN THÀNH THỊ & TIỆN ÍCH CẤP 60+ (LOGISTICS & ITEMS) // ========================================================= public int KeyPhuVirtualCode { get; set; } = 0x35; // Mặc định phím 5 public int KeyBagVirtualCode { get; set; } = 0x73; // Mặc định F4 public int ReturnIntervalMinutes { get; set; } = 30; public int MapLoadDelayMs { get; set; } = Constants.DefaultMapLoadDelayMs; public bool PeriodicReturnEnabled { get; set; } = true; public bool AutoRepairEnabled { get; set; } = true; public int RepairMode { get; set; } = 1; // 0: Túi đồ nghề, 1: Thợ Rèn public int BlacksmithNpcX { get; set; } = 400; public int BlacksmithNpcY { get; set; } = 300; public int RepairItemX { get; set; } = 653; public int RepairItemY { get; set; } = 345; public bool RepairDialogSelectOption1 { get; set; } = true; public int RepairDialogDelayMs { get; set; } = 400; // Bắt tùy chọn NPC theo nội dung text (chống 100% lỗi server chèn sự kiện hoặc đổi menu) public bool NpcDialogMatchByText { get; set; } = true; public string RepairMenuKeywords { get; set; } = NpcDialogTextMatcher.DefaultRepairKeywords; public string RepairSubMenuKeywords { get; set; } = NpcDialogTextMatcher.DefaultRepairSubMenuKeywords; public string MedicineMenuKeywords { get; set; } = NpcDialogTextMatcher.DefaultMedicineKeywords; public string TravelMenuKeywords { get; set; } = NpcDialogTextMatcher.DefaultTravelKeywords; public int NpcDialogFallbackOption { get; set; } = 1; public bool AutoBeginnerMedicineEnabled { get; set; } = true; public int MedicineIntervalMinutes { get; set; } = 180; public int MedicineItemX { get; set; } = 575; public int MedicineItemY { get; set; } = 345; public long LastMedicineUseTimestamp { get; set; } = 0; public bool AutoTravelBackEnabled { get; set; } = false; public int TravelItemX { get; set; } = 740; public int TravelItemY { get; set; } = 345; public string TravelMenuKeys { get; set; } = "2,5,4"; // Mặc định Lão Hổ Động (2: Bản đồ luyện công -> 5: Cấp 50-59 -> 4: Lão Hổ Động) public int TravelMenuDelayMs { get; set; } = 600; // Tự động lưu rương / điểm hồi sinh tại thành thị (Dương Châu) public bool AutoSaveRespawnEnabled { get; set; } = true; public int RespawnMenuKey { get; set; } = 3; // Phím 3 trên menu Thần Hành Phù: Lưu điểm hồi sinh public string TargetCityName { get; set; } = "Dương Châu"; public string TargetTrainingSpot { get; set; } = "Lão Hổ Động"; // Tên nhân vật và tiến trình game đã chọn lần cuối public string CharacterName { get; set; } = string.Empty; public string LastSelectedTitle { get; set; } = string.Empty; private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true }; private static readonly string DefaultConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json"); public static string GetConfigPathForCharacter(string? characterName) { if (string.IsNullOrWhiteSpace(characterName)) return DefaultConfigPath; string safeName = string.Concat(characterName.Split(Path.GetInvalidFileNameChars())).Trim(); if (string.IsNullOrEmpty(safeName)) return DefaultConfigPath; return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"config_{safeName}.json"); } public static BotConfig Load(string? path = null) { string filePath = path ?? DefaultConfigPath; try { if (File.Exists(filePath)) { string json = File.ReadAllText(filePath); var config = JsonSerializer.Deserialize(json); if (config != null) return config; } } catch { // Fallback về giá trị mặc định nếu file lỗi } return new BotConfig(); } public static BotConfig LoadForCharacter(string? characterName) { string specificPath = GetConfigPathForCharacter(characterName); BotConfig cfg; if (File.Exists(specificPath)) { cfg = Load(specificPath); } else { cfg = Load(DefaultConfigPath); } if (!string.IsNullOrEmpty(characterName)) cfg.CharacterName = characterName; // Tự động gán cấu hình môn phái, chiêu thức và vai trò tổ đội cho 4 nhân vật if (string.Equals(characterName, "BoCuaCacCon", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(cfg.DetectedSect)) cfg.DetectedSect = "Cái Bang"; if (string.IsNullOrEmpty(cfg.MainAttackSkillName)) cfg.MainAttackSkillName = "Kháng Long Hữu Hối"; if (string.IsNullOrEmpty(cfg.Buff1SkillName)) { cfg.Buff1SkillName = "Túy Điệp Cuồng Vũ"; cfg.Buff1Enabled = true; cfg.Buff1IntervalSeconds = 60; } cfg.IsPartyLeader = false; cfg.LockCurrentSpot = true; cfg.AttackRadius = 0; cfg.FollowLeaderEnabled = true; cfg.LeaderName = "ConCuaBoMe"; cfg.FollowDistance = 100; cfg.AutoPartyEnabled = true; } else if (string.Equals(characterName, "ConCuaBoMe", StringComparison.OrdinalIgnoreCase)) { cfg.DetectedSect = "Thiếu Lâm"; if (string.IsNullOrEmpty(cfg.MainAttackSkillName)) cfg.MainAttackSkillName = "Kim Cang Phục Ma"; if (string.IsNullOrEmpty(cfg.Buff1SkillName)) { cfg.Buff1SkillName = "Bất Động Minh Vương"; cfg.Buff1Enabled = true; cfg.Buff1IntervalSeconds = 60; } cfg.IsPartyLeader = true; cfg.PartyMembers = "BoCuaCacCon,MeCuaCacCon,ConGailCung"; cfg.LockCurrentSpot = false; cfg.AttackRadius = 1000; cfg.FollowLeaderEnabled = false; } else if (string.Equals(characterName, "ConGailCung", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(cfg.DetectedSect)) cfg.DetectedSect = "Ngũ Độc"; if (string.IsNullOrEmpty(cfg.MainAttackSkillName)) cfg.MainAttackSkillName = "Bách Độc Xuyên Tâm"; cfg.IsPartyLeader = false; cfg.FollowLeaderEnabled = true; cfg.LeaderName = "ConCuaBoMe"; cfg.FollowDistance = 100; cfg.AutoPartyEnabled = true; } else if (string.Equals(characterName, "MeCuaCacCon", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(cfg.DetectedSect)) cfg.DetectedSect = "Nga My"; if (string.IsNullOrEmpty(cfg.MainAttackSkillName)) cfg.MainAttackSkillName = "Phật Quang Phổ Chiếu"; cfg.NgaMyHealEnabled = true; cfg.IsPartyLeader = false; cfg.FollowLeaderEnabled = true; cfg.LeaderName = "ConCuaBoMe"; cfg.FollowDistance = 100; cfg.AutoPartyEnabled = true; } else if (string.IsNullOrEmpty(cfg.MainAttackSkillName) && !string.IsNullOrEmpty(cfg.DetectedSect)) { cfg.MainAttackSkillName = SkillScanner.GetDefaultAttackSkillForSect(cfg.DetectedSect); } return cfg; } public void Save(string? path = null) { string filePath = path ?? DefaultConfigPath; try { string json = JsonSerializer.Serialize(this, JsonOptions); File.WriteAllText(filePath, json); } catch { // Bỏ qua lỗi IO nhẹ } } public void SaveForCharacter(string? characterName = null) { string targetName = !string.IsNullOrEmpty(characterName) ? characterName : CharacterName; string specificPath = GetConfigPathForCharacter(targetName); Save(specificPath); } }