using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.GameTask.AutoFight.Model; using BetterGenshinImpact.GameTask.AutoFight.Script; using BetterGenshinImpact.GameTask.Model.Enum; using BetterGenshinImpact.Model; using BetterGenshinImpact.Service; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using static BetterGenshinImpact.GameTask.Common.TaskControl; namespace BetterGenshinImpact.GameTask.AutoFight; /// /// 一键战斗宏 /// public class OneKeyFightTask : Singleton { public static readonly string HoldOnMode = "按住时重复"; public static readonly string TickMode = "触发"; private Dictionary>? _avatarMacros; private CancellationTokenSource? _cts = null; private Task? _fightTask; private bool _isKeyDown = false; private int activeMacroPriority = -1; private DateTime _lastUpdateTime = DateTime.MinValue; private CombatScenes? _currentCombatScenes; public void KeyDown() { if (_isKeyDown || !IsEnabled()) { return; } _isKeyDown = true; if (activeMacroPriority != TaskContext.Instance().Config.MacroConfig.CombatMacroPriority || IsAvatarMacrosEdited()) { activeMacroPriority = TaskContext.Instance().Config.MacroConfig.CombatMacroPriority; _avatarMacros = LoadAvatarMacros(); Logger.LogInformation("加载一键宏配置完成"); } if (IsHoldOnMode()) { if (_cts == null || _cts.Token.IsCancellationRequested) { _cts = new CancellationTokenSource(); _fightTask = FightTask(_cts.Token); if (!_fightTask.IsCompleted) { _fightTask.Start(); } } } else if (IsTickMode()) { if (_cts == null || _cts.Token.IsCancellationRequested) { _cts = new CancellationTokenSource(); _fightTask = FightTask(_cts.Token); if (!_fightTask.IsCompleted) { _fightTask.Start(); } } else { _cts.Cancel(); } } } public void KeyUp() { _isKeyDown = false; if (!IsEnabled()) { return; } if (IsHoldOnMode()) { _cts?.Cancel(); } } // public void Run() // { // if (!IsEnabled()) // { // return; // } // _avatarMacros ??= LoadAvatarMacros(); // // if (IsHoldOnMode()) // { // if (_fightTask == null || _fightTask.IsCompleted) // { // _fightTask = FightTask(_cts); // _fightTask.Start(); // } // Thread.Sleep(100); // } // else if (IsTickMode()) // { // if (_cts.Token.IsCancellationRequested) // { // _cts = new CancellationTokenSource(); // Task.Run(() => FightTask(_cts)); // } // else // { // _cts.Cancel(); // } // } // } /// /// 循环执行战斗宏 /// private Task FightTask(CancellationToken ct) { // 切换截图模式 var dispatcherCaptureMode = TaskTriggerDispatcher.Instance().GetCacheCaptureMode(); if (dispatcherCaptureMode != DispatcherCaptureModeEnum.CacheCaptureWithTrigger) { TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger); Sleep(TaskContext.Instance().Config.TriggerInterval * 2, ct); // 等待缓存图像 } var imageRegion = CaptureToRectArea(); var combatScenes = new CombatScenes().InitializeTeam(imageRegion); if (!combatScenes.CheckTeamInitialized()) { if (_currentCombatScenes == null) { Logger.LogError("首次队伍角色识别失败"); return Task.CompletedTask; } else { Logger.LogWarning("队伍角色识别失败,使用上次识别结果,队伍未切换时无影响"); } } else { _currentCombatScenes = combatScenes; } // 找到出战角色 var activeAvatar = _currentCombatScenes.Avatars.First(avatar => avatar.IsActive(imageRegion)); if (_avatarMacros != null && _avatarMacros.TryGetValue(activeAvatar.Name, out var combatCommands)) { return new Task(() => { Logger.LogInformation("→ {Name}执行宏", activeAvatar.Name); while (!ct.IsCancellationRequested && IsEnabled()) { if (IsHoldOnMode() && !_isKeyDown) { break; } // 通用化战斗策略 foreach (var command in combatCommands) { command.Execute(activeAvatar); } } Logger.LogInformation("→ {Name}停止宏", activeAvatar.Name); }); } else { Logger.LogWarning("→ {Name}配置[{Priority}]为空,请先配置一键宏", activeAvatar.Name, activeMacroPriority); return Task.CompletedTask; } } public Dictionary> LoadAvatarMacros() { var jsonPath = Global.Absolute("User/avatar_macro.json"); var json = File.ReadAllText(jsonPath); _lastUpdateTime = File.GetLastWriteTime(jsonPath); var avatarMacros = JsonSerializer.Deserialize>(json, ConfigService.JsonOptions); if (avatarMacros == null) { return []; } var result = new Dictionary>(); foreach (var avatarMacro in avatarMacros) { var commands = avatarMacro.LoadCommands(); if (commands != null) { result.Add(avatarMacro.Name, commands); } } return result; } public bool IsAvatarMacrosEdited() { // 通过修改时间判断是否编辑过 var jsonPath = Global.Absolute("User/avatar_macro.json"); var lastWriteTime = File.GetLastWriteTime(jsonPath); return lastWriteTime > _lastUpdateTime; } public static bool IsEnabled() { return TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled; } public static bool IsHoldOnMode() { return TaskContext.Instance().Config.MacroConfig.CombatMacroHotkeyMode == HoldOnMode; } public static bool IsTickMode() { return TaskContext.Instance().Config.MacroConfig.CombatMacroHotkeyMode == TickMode; } }