diff --git a/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs index c6e96086..13339774 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/OneKeyFightTask.cs @@ -167,9 +167,10 @@ public class OneKeyFightTask : Singleton { return new Task(() => { - Logger.LogInformation("→ {Name}执行宏", activeAvatar.Name); + var round = 1; while (!ct.IsCancellationRequested && IsEnabled()) { + Logger.LogInformation("→ {Name}执行宏 (第{Round}轮)", activeAvatar.Name, round); if (IsHoldOnMode() && !_isKeyDown) { break; @@ -178,8 +179,14 @@ public class OneKeyFightTask : Singleton // 通用化战斗策略 foreach (var command in combatCommands) { + if (command.ActivatingRound != null && command.ActivatingRound.Count > 0 && !command.ActivatingRound.Contains(round)) + { + // 跳过强制首轮指令 + continue; + } command.Execute(activeAvatar); } + round++; } Logger.LogInformation("→ {Name}停止宏", activeAvatar.Name); diff --git a/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs b/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs index 34b1e75c..1c37f1bc 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs @@ -14,6 +14,8 @@ public class CombatCommand public List? Args { get; set; } + public List ActivatingRound { get; set; } + public CombatCommand(string name, string command) { Name = name.Trim(); @@ -63,6 +65,11 @@ public class CombatCommand } } } + + public override string ToString() + { + return $""; + } public void Execute(CombatScenes combatScenes, CombatCommand? lastCommand = null) { @@ -264,6 +271,10 @@ public class CombatCommand { avatar.KeyPress(Args![0]); } + else if (Method == Method.Round) + { + // 作为回合标记使用,不做任何操作 + } else { throw new NotImplementedException(); diff --git a/BetterGenshinImpact/GameTask/AutoFight/Script/CombatScriptParser.cs b/BetterGenshinImpact/GameTask/AutoFight/Script/CombatScriptParser.cs index e8e500b7..4761fb5e 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Script/CombatScriptParser.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Script/CombatScriptParser.cs @@ -131,7 +131,70 @@ public class CombatScriptParser return oneLineCombatCommands; } - public static List ParseLineCommands(string lineWithoutAvatar, string avatarName) + public static List ParseRoundCommand(CombatCommand roundCommand) { + // 解析round命令的入参,返回一个整数列表,代表在哪些回合执行后续指令 + // 支持Round(1)、Round(1,3,5)、Round(2-4)、Round(1,3-5)等格式 + var activatingRounds = new List(); + if (roundCommand.Args == null || roundCommand.Args.Count == 0) { + Logger.LogError("round方法必须有入参,代表在哪些回合执行后续指令,例:round(1)、round(1,3-5)"); + throw new ArgumentException("round方法必须有入参,代表在哪些回合执行后续指令,例:round(1)、round(1,3-5)"); + } + foreach (var arg in roundCommand.Args) { + if (arg.Contains('-')) { + // 范围 + var parts = arg.Split('-', StringSplitOptions.TrimEntries); + if (parts.Length != 2) { + Logger.LogError("round方法的入参格式错误,例:round(1-3)"); + throw new ArgumentException("round方法的入参格式错误,例:round(1-3)"); + } + var start = int.Parse(parts[0]); + var end = int.Parse(parts[1]); + if (start > end || start <= 0) { + Logger.LogError("round方法的入参格式错误,起始回合必须小于等于结束回合且大于0,例:round(1-3)"); + throw new ArgumentException("round方法的入参格式错误,起始回合必须小于等于结束回合且大于0,例:round(1-3)"); + } + for (int i = start; i <= end; i++) { + activatingRounds.Add(i); + } + } else { + // 单个回合 + var round = int.Parse(arg); + if (round <= 0) { + Logger.LogError("round方法的入参格式错误,回合数必须大于0,例:round(1)"); + throw new ArgumentException("round方法的入参格式错误,回合数必须大于0,例:round(1)"); + } + activatingRounds.Add(round); + } + } + return activatingRounds; + } + + public static List ParseLineCommands(string lineWithoutAvatar, string avatarName) { + var parts = lineWithoutAvatar.Split("|", StringSplitOptions.RemoveEmptyEntries); + var fullCombatCommands = new List(); + foreach (var part in parts) + { + var combatCommands = ParseLinePart(part, avatarName); + if (combatCommands.Count > 0 && combatCommands[0].Method == Method.Round) { + // 遇到round指令,作为回合分隔符使用,不加入最终指令列表 + var roundCommand = combatCommands[0]; + var activatingRounds = ParseRoundCommand(roundCommand); + combatCommands.RemoveAt(0); + foreach (var combatCommand in combatCommands) { + + combatCommand.ActivatingRound = activatingRounds; + } + } + fullCombatCommands.AddRange(combatCommands); + } + foreach (var combatCommand in fullCombatCommands) + { + Logger.LogDebug("解析战斗脚本命令:{cmd}", combatCommand.ToString()); + } + return fullCombatCommands; + } + + public static List ParseLinePart(string lineWithoutAvatar, string avatarName) { var oneLineCombatCommands = new List(); var commandArray = lineWithoutAvatar.Split(",", StringSplitOptions.RemoveEmptyEntries); diff --git a/BetterGenshinImpact/GameTask/AutoFight/Script/Method.cs b/BetterGenshinImpact/GameTask/AutoFight/Script/Method.cs index bbe6fb6d..71eec833 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Script/Method.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Script/Method.cs @@ -31,6 +31,7 @@ public class Method public static readonly Method KeyDown = new(["keydown"]); public static readonly Method KeyUp = new(["keyup"]); public static readonly Method KeyPress = new(["keypress"]); + public static readonly Method Round = new(["round"]); public static IEnumerable Values { @@ -60,6 +61,7 @@ public class Method yield return KeyDown; yield return KeyUp; yield return KeyPress; + yield return Round; } }