diff --git a/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageConfig.cs b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageConfig.cs index 408e838e..5762ca55 100644 --- a/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageConfig.cs +++ b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageConfig.cs @@ -14,6 +14,10 @@ public partial class AutoArtifactSalvageConfig : ObservableObject Output = hasATK && hasDEF; })(ArtifactStat);"; + // JavaScript + [ObservableProperty] + private string _artifactSetFilter = ""; + // 正则表达式 [Obsolete] [ObservableProperty] diff --git a/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs index fd393bd8..5207c3f0 100644 --- a/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs +++ b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs @@ -7,6 +7,7 @@ using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.Common.Job; +using BetterGenshinImpact.GameTask.GetGridIcons; using BetterGenshinImpact.GameTask.Model.Area; using BetterGenshinImpact.GameTask.Model.GameUI; using BetterGenshinImpact.Helpers; @@ -16,6 +17,7 @@ using Microsoft.ClearScript; using Microsoft.ClearScript.V8; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; +using Microsoft.ML.OnnxRuntime; using OpenCvSharp; using System; using System.Collections.Frozen; @@ -51,6 +53,8 @@ public class AutoArtifactSalvageTask : ISoloTask private readonly string? javaScript; + private readonly string? artifactSetFilter; + private readonly int? maxNumToCheck; private readonly RecognitionFailurePolicy? recognitionFailurePolicy; @@ -65,6 +69,7 @@ public class AutoArtifactSalvageTask : ISoloTask { this.star = param.Star; this.javaScript = param.JavaScript; + this.artifactSetFilter = param.ArtifactSetFilter; this.maxNumToCheck = param.MaxNumToCheck; this.recognitionFailurePolicy = param.RecognitionFailurePolicy; this.logger = logger ?? App.GetLogger(); @@ -228,7 +233,11 @@ public class AutoArtifactSalvageTask : ISoloTask } } - Bv.ClickWhiteConfirmButton(ra4); + using var quickSelectConfirmBtn = ra4.Find(ElementAssets.Instance.BtnWhiteConfirm); + if (quickSelectConfirmBtn.IsExist()) + { + quickSelectConfirmBtn.Click(); + } await Delay(1500, ct); @@ -264,6 +273,38 @@ public class AutoArtifactSalvageTask : ISoloTask // 分解5星 if (javaScript != null) { + if (!string.IsNullOrWhiteSpace(this.artifactSetFilter)) + { + // 其实是点击筛选按钮……快速选择确认的这个按钮正好和筛选按钮位置重合,摆烂直接用了 + quickSelectConfirmBtn.Click(); + await Delay(400, ct); + // 点击所属套装 + ra5.ClickTo(315, 205); + await Delay(1000, ct); + // 遍历套装Grid勾选套装 + using InferenceSession session = GridIconsAccuracyTestTask.LoadModel(out Dictionary prototypes); + ArtifactSetFilterScreen gridScreen = new ArtifactSetFilterScreen(new GridParams(new Rect(40, 100, 1300, 852), 2, 3, 40, 40, 0.024), this.logger, this.ct); + await foreach (ImageRegion itemRegion in gridScreen) + { + using Mat img125 = GetGridIconsTask.CropResizeArtifactSetFilterGridIcon(itemRegion); + (string predName, _) = GridIconsAccuracyTestTask.Infer(img125, session, prototypes); + if (this.artifactSetFilter.Contains(predName)) + { + itemRegion.Click(); + await Delay(100, ct); + } + } + // 点击确认筛选 + using var confirmFilterBtnRegion = CaptureToRectArea(); + Bv.ClickWhiteConfirmButton(confirmFilterBtnRegion); + await Delay(1500, ct); + // 点击确认 + using var confirmBtnRegion = CaptureToRectArea(); + Bv.ClickWhiteConfirmButton(confirmBtnRegion); + await Delay(600, ct); + } + + // 逐一点选查看面板筛选 await Salvage5Star(); logger.LogInformation("筛选完毕,请复查并手动分解"); } diff --git a/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTaskParam.cs b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTaskParam.cs index dd170723..0d7b4e69 100644 --- a/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTaskParam.cs +++ b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTaskParam.cs @@ -9,16 +9,18 @@ namespace BetterGenshinImpact.GameTask.AutoArtifactSalvage { public class AutoArtifactSalvageTaskParam : BaseTaskParam { - public AutoArtifactSalvageTaskParam(int star, string? javaScript, int? maxNumToCheck, RecognitionFailurePolicy? recognitionFailurePolicy, CultureInfo? cultureInfo = null, IStringLocalizer? stringLocalizer = null) : base(cultureInfo, stringLocalizer) + public AutoArtifactSalvageTaskParam(int star, string? javaScript, string? artifactSetFilter, int? maxNumToCheck, RecognitionFailurePolicy? recognitionFailurePolicy, CultureInfo? cultureInfo = null, IStringLocalizer? stringLocalizer = null) : base(cultureInfo, stringLocalizer) { Star = star; JavaScript = javaScript; + ArtifactSetFilter = artifactSetFilter; MaxNumToCheck = maxNumToCheck; RecognitionFailurePolicy = recognitionFailurePolicy; } public int Star { get; set; } public string? JavaScript { get; set; } + public string? ArtifactSetFilter { get; set; } public int? MaxNumToCheck { get; set; } public RecognitionFailurePolicy? RecognitionFailurePolicy { get; set; } } diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index 285edf77..389e8c1c 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -1312,6 +1312,6 @@ public class AutoDomainTask : ISoloTask star = 4; } - await new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(star, javaScript: null, maxNumToCheck: null, recognitionFailurePolicy: null)).Start(_ct); + await new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(star, javaScript: null, artifactSetFilter: null, maxNumToCheck: null, recognitionFailurePolicy: null)).Start(_ct); } } diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/emberglow bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/emberglow bait.png deleted file mode 100644 index f7b665c6..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/emberglow bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/fake fly bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/fake fly bait.png deleted file mode 100644 index c6ee6db5..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/fake fly bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/false worm bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/false worm bait.png deleted file mode 100644 index a2d26aef..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/false worm bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/flashing maintenance mek bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/flashing maintenance mek bait.png deleted file mode 100644 index b34e4bef..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/flashing maintenance mek bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/fruit paste bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/fruit paste bait.png deleted file mode 100644 index 7a3e2f3c..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/fruit paste bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/redrot bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/redrot bait.png deleted file mode 100644 index 5d43fd68..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/redrot bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/sour bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/sour bait.png deleted file mode 100644 index 633f2680..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/sour bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/spinelgrain bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/spinelgrain bait.png deleted file mode 100644 index cf8212e5..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/spinelgrain bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/sugardew bait.png b/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/sugardew bait.png deleted file mode 100644 index 5afe361d..00000000 Binary files a/BetterGenshinImpact/GameTask/AutoFishing/Assets/1920x1080/bait/sugardew bait.png and /dev/null differ diff --git a/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTask.cs b/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTask.cs index d58a54be..c313867b 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/AutoFishingTask.cs @@ -1,30 +1,35 @@ -using BetterGenshinImpact.GameTask.Common; -using Microsoft.Extensions.Logging; -using System; -using System.Threading; -using System.Threading.Tasks; -using BetterGenshinImpact.GameTask.Common.BgiVision; +using BehaviourTree; using BehaviourTree.Composites; using BehaviourTree.FluentBuilder; -using BehaviourTree; -using BetterGenshinImpact.Core.Simulator; -using BetterGenshinImpact.View.Drawable; -using BetterGenshinImpact.GameTask.AutoFishing.Assets; -using Vanara.PInvoke; -using System.Linq; -using BetterGenshinImpact.GameTask.AutoFishing.Model; -using BetterGenshinImpact.GameTask.Common.Job; -using Fischless.WindowsInput; -using BetterGenshinImpact.GameTask.Model.Area; -using BetterGenshinImpact.Core.Recognition.ONNX; -using static Vanara.PInvoke.User32; -using BetterGenshinImpact.GameTask.AutoFight.Assets; -using System.Globalization; -using Microsoft.Extensions.Localization; -using BetterGenshinImpact.Helpers; using BetterGenshinImpact.Core.Recognition.OCR; +using BetterGenshinImpact.Core.Recognition.ONNX; +using BetterGenshinImpact.Core.Simulator; +using BetterGenshinImpact.GameTask.AutoFight.Assets; +using BetterGenshinImpact.GameTask.AutoFishing.Assets; +using BetterGenshinImpact.GameTask.AutoFishing.Model; +using BetterGenshinImpact.GameTask.Common; +using BetterGenshinImpact.GameTask.Common.BgiVision; +using BetterGenshinImpact.GameTask.Common.Job; +using BetterGenshinImpact.GameTask.GetGridIcons; +using BetterGenshinImpact.GameTask.Model.Area; +using BetterGenshinImpact.Helpers; +using BetterGenshinImpact.Helpers.Extensions; +using BetterGenshinImpact.View.Drawable; using Compunet.YoloSharp; +using Fischless.WindowsInput; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using Microsoft.ML.OnnxRuntime; +using OpenCvSharp; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Vanara.PInvoke; +using static Vanara.PInvoke.User32; namespace BetterGenshinImpact.GameTask.AutoFishing { @@ -51,6 +56,7 @@ namespace BetterGenshinImpact.GameTask.AutoFishing this._ct = ct; IOcrService ocrService = OcrFactory.Paddle; + using InferenceSession session = GridIconsAccuracyTestTask.LoadModel(out Dictionary prototypes); Blackboard blackboard = new Blackboard(_predictor, this.Sleep, AutoFishingAssets.Instance); @@ -64,7 +70,7 @@ namespace BetterGenshinImpact.GameTask.AutoFishing .PushLeaf(() => new TurnAround("转圈圈调整视角", blackboard, _logger, param.SaveScreenshotOnKeyTick, input)) .PushLeaf(() => new FindFishTimeout("找到鱼", 20, blackboard, _logger, param.SaveScreenshotOnKeyTick)) .End() - .PushLeaf(() => new EnterFishingMode("进入钓鱼模式", blackboard, _logger, param.SaveScreenshotOnKeyTick, input, cultureInfo: param.GameCultureInfo, stringLocalizer: param.StringLocalizer)) + .PushLeaf(() => new EnterFishingMode("进入钓鱼模式", blackboard, _logger, param.SaveScreenshotOnKeyTick, input, session, prototypes, cultureInfo: param.GameCultureInfo, stringLocalizer: param.StringLocalizer)) .UntilFailed(@"\") .Sequence("一直钓鱼直到没鱼") .AlwaysSucceed(@"\") @@ -79,7 +85,7 @@ namespace BetterGenshinImpact.GameTask.AutoFishing .End() .PushLeaf(() => new FindFishTimeout("确认初始状态和找到鱼", 10, blackboard, _logger, param.SaveScreenshotOnKeyTick)) .End() - .PushLeaf(() => new ChooseBait("选择鱼饵", blackboard, _logger, param.SaveScreenshotOnKeyTick, TaskContext.Instance().SystemInfo, input)) + .PushLeaf(() => new ChooseBait("选择鱼饵", blackboard, _logger, param.SaveScreenshotOnKeyTick, TaskContext.Instance().SystemInfo, input, session, prototypes)) .MySimpleParallel("抛竿直到成功或出错", policy: SimpleParallelPolicy.OnlyOneMustSucceed) .UntilSuccess("重复抛竿") .Sequence("-") @@ -345,6 +351,8 @@ namespace BetterGenshinImpact.GameTask.AutoFishing { private readonly IInputSimulator input; private readonly Blackboard blackboard; + private readonly InferenceSession session; + private readonly Dictionary prototypes; private readonly TimeProvider timeProvider; private DateTimeOffset? pressFWaitEndTime; private DateTimeOffset? clickWhiteConfirmButtonWaitEndTime; @@ -352,11 +360,13 @@ namespace BetterGenshinImpact.GameTask.AutoFishing private readonly string fishingLocalizedString; public EnterFishingMode(string name, Blackboard blackboard, ILogger logger, bool saveScreenshotOnTerminate, - IInputSimulator input, TimeProvider? timeProvider = null, CultureInfo? cultureInfo = null, IStringLocalizer? stringLocalizer = null) : base(name, + IInputSimulator input, InferenceSession session, Dictionary prototypes, TimeProvider? timeProvider = null, CultureInfo? cultureInfo = null, IStringLocalizer? stringLocalizer = null) : base(name, logger, saveScreenshotOnTerminate) { this.blackboard = blackboard; this.input = input; + this.session = session; + this.prototypes = prototypes; this.timeProvider = timeProvider ?? TimeProvider.System; this.fishingLocalizedString = stringLocalizer == null ? "钓鱼" : stringLocalizer.WithCultureGet(cultureInfo, "钓鱼"); } @@ -380,7 +390,17 @@ namespace BetterGenshinImpact.GameTask.AutoFishing clickWhiteConfirmButtonWaitEndTime < timeProvider.GetLocalNow()) && Bv.ClickWhiteConfirmButton(imageRegion)) { - logger.LogInformation("点击开始钓鱼"); + Mat subMat = imageRegion.SrcMat.SubMat(new Rect((int)(0.824 * imageRegion.Width), (int)(0.669 * imageRegion.Height), (int)(0.065 * imageRegion.Width), (int)(0.065 * imageRegion.Width))); + using Mat resized = subMat.Resize(new Size(125, 125)); + (string predName, _) = GridIconsAccuracyTestTask.Infer(resized, this.session, this.prototypes); + if (predName.TryGetEnumValueFromDescription(out this.blackboard.selectedBait)) + { + logger.LogInformation("点击开始钓鱼,当前鱼饵为{bait}", this.blackboard.selectedBait.Value.GetDescription()); + } + else + { + logger.LogInformation("点击开始钓鱼,当前鱼饵未识别"); + } this.blackboard.pitchReset = true; diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Behaviours.cs b/BetterGenshinImpact/GameTask/AutoFishing/Behaviours.cs index c06628b5..2aef44cc 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/Behaviours.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/Behaviours.cs @@ -1,26 +1,30 @@ using BehaviourTree; using BetterGenshinImpact.Core.Recognition; using BetterGenshinImpact.Core.Recognition.OCR; +using BetterGenshinImpact.Core.Recognition.OpenCv; +using BetterGenshinImpact.Core.Simulator; using BetterGenshinImpact.GameTask.AutoFishing.Model; +using BetterGenshinImpact.GameTask.GetGridIcons; +using BetterGenshinImpact.GameTask.Model; using BetterGenshinImpact.GameTask.Model.Area; +using BetterGenshinImpact.GameTask.Model.GameUI; using BetterGenshinImpact.Helpers; +using BetterGenshinImpact.Helpers.Extensions; using BetterGenshinImpact.View.Drawable; +using Compunet.YoloSharp; +using Fischless.WindowsInput; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; +using Microsoft.ML.OnnxRuntime; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; +using System.Linq; using static Vanara.PInvoke.User32; using Color = System.Drawing.Color; using Pen = System.Drawing.Pen; -using System.Linq; -using Fischless.WindowsInput; -using BetterGenshinImpact.Core.Recognition.OpenCv; -using BetterGenshinImpact.Core.Simulator; -using BetterGenshinImpact.GameTask.Model; -using System.Globalization; -using Compunet.YoloSharp; -using Microsoft.Extensions.Localization; namespace BetterGenshinImpact.GameTask.AutoFishing { @@ -66,11 +70,11 @@ namespace BetterGenshinImpact.GameTask.AutoFishing { blackboard.fishpond = fishpond; - string[] chooseBaitfailuresIgnoredBaits = blackboard.chooseBaitFailures.GroupBy(f => f).Where(g => g.Count() >= ChooseBait.MAX_FAILED_TIMES).Select(g => g.Key).ToArray(); - string[] throwRodNoTargetFishfailuresIgnoredBaits = blackboard.throwRodNoBaitFishFailures.GroupBy(f => f).Where(g => g.Count() >= ThrowRod.MAX_NO_BAIT_FISH_TIMES).Select(g => g.Key).ToArray(); + BaitType[] chooseBaitfailuresIgnoredBaits = blackboard.chooseBaitFailures.GroupBy(f => f).Where(g => g.Count() >= ChooseBait.MAX_FAILED_TIMES).Select(g => g.Key).ToArray(); + BaitType[] throwRodNoTargetFishfailuresIgnoredBaits = blackboard.throwRodNoBaitFishFailures.GroupBy(f => f).Where(g => g.Count() >= ThrowRod.MAX_NO_BAIT_FISH_TIMES).Select(g => g.Key).ToArray(); logger.LogInformation("定位到鱼塘:" + string.Join('、', fishpond.Fishes.GroupBy(f => f.FishType) - .Select(g => $"{g.Key.ChineseName}{g.Count()}条" + ((chooseBaitfailuresIgnoredBaits.Contains(g.Key.BaitName) || throwRodNoTargetFishfailuresIgnoredBaits.Contains(g.Key.BaitName)) ? "(忽略)" : "")) + .Select(g => $"{g.Key.ChineseName}{g.Count()}条" + ((chooseBaitfailuresIgnoredBaits.Contains(g.Key.BaitType) || throwRodNoTargetFishfailuresIgnoredBaits.Contains(g.Key.BaitType)) ? "(忽略)" : "")) )); int i = 0; foreach (var fish in fishpond.Fishes) @@ -80,8 +84,8 @@ namespace BetterGenshinImpact.GameTask.AutoFishing blackboard.Sleep(1000); drawContent.ClearAll(); if (blackboard.fishpond.Fishes.Any(f => - !chooseBaitfailuresIgnoredBaits.Contains(f.FishType.BaitName) - && !throwRodNoTargetFishfailuresIgnoredBaits.Contains(f.FishType.BaitName))) + !chooseBaitfailuresIgnoredBaits.Contains(f.FishType.BaitType) + && !throwRodNoTargetFishfailuresIgnoredBaits.Contains(f.FishType.BaitType))) { return BehaviourStatus.Succeeded; } @@ -100,6 +104,8 @@ namespace BetterGenshinImpact.GameTask.AutoFishing { private readonly ISystemInfo systemInfo; private readonly IInputSimulator input; + private readonly InferenceSession session; + private readonly Dictionary prototypes; private readonly Blackboard blackboard; private readonly TimeProvider timeProvider; private DateTimeOffset? chooseBaitUIOpenWaitEndTime; // 等待选鱼饵界面出现并尝试找鱼饵的结束时间 @@ -110,11 +116,13 @@ namespace BetterGenshinImpact.GameTask.AutoFishing /// /// /// - public ChooseBait(string name, Blackboard blackboard, ILogger logger, bool saveScreenshotOnTerminat, ISystemInfo systemInfo, IInputSimulator input, TimeProvider? timeProvider = null) : base(name, logger, saveScreenshotOnTerminat) + public ChooseBait(string name, Blackboard blackboard, ILogger logger, bool saveScreenshotOnTerminat, ISystemInfo systemInfo, IInputSimulator input, InferenceSession session, Dictionary prototypes, TimeProvider? timeProvider = null) : base(name, logger, saveScreenshotOnTerminat) { this.blackboard = blackboard; this.systemInfo = systemInfo; this.input = input; + this.session = session; + this.prototypes = prototypes; this.timeProvider = timeProvider ?? TimeProvider.System; } @@ -122,7 +130,7 @@ namespace BetterGenshinImpact.GameTask.AutoFishing { if (this.Status == BehaviourStatus.Ready) { - if (blackboard.fishpond.Fishes.Any(f => f.FishType.BaitName == blackboard.selectedBaitName)) // 如果该种鱼没钓完就不用换饵 + if (blackboard.fishpond.Fishes.Any(f => f.FishType.BaitType == blackboard.selectedBait)) // 如果该种鱼没钓完就不用换饵 { return BehaviourStatus.Succeeded; } @@ -136,72 +144,86 @@ namespace BetterGenshinImpact.GameTask.AutoFishing return BehaviourStatus.Running; } - blackboard.selectedBaitName = blackboard.fishpond.Fishes.GroupBy(f => f.FishType.BaitName) + blackboard.selectedBait = blackboard.fishpond.Fishes.GroupBy(f => f.FishType.BaitType) .Where(b => !blackboard.chooseBaitFailures.GroupBy(f => f).Where(g => g.Count() >= MAX_FAILED_TIMES).Any(g => g.Key == b.Key)) // 不能是已经失败两次的饵 .OrderByDescending(g => g.Count()).First().Key; // 选择最多鱼吃的饵料 - logger.LogInformation("选择鱼饵 {Text}", BaitType.FromName(blackboard.selectedBaitName).ChineseName); + logger.LogInformation("选择鱼饵 {Text}", blackboard.selectedBait.GetDescription()); // 寻找鱼饵 - var ro = new RecognitionObject - { - Name = "ChooseBait", - RecognitionType = RecognitionTypes.TemplateMatch, - TemplateImageMat = GameTaskManager.LoadAssetImage("AutoFishing", $"bait\\{blackboard.selectedBaitName}.png", systemInfo), - Threshold = 0.8, - Use3Channels = true, - DrawOnWindow = false - }.InitTemplate(); + using ImageRegion singleRowGrid = imageRegion.DeriveCrop(0.28 * imageRegion.Width, 0.37 * imageRegion.Height, 0.45 * imageRegion.Width, 0.22 * imageRegion.Height); + using Mat grey = singleRowGrid.SrcMat.CvtColor(ColorConversionCodes.BGR2GRAY); + using Mat canny = grey.Canny(20, 40); - using var resRa = imageRegion.Find(ro); - if (resRa.IsEmpty()) - { - if (timeProvider.GetLocalNow() >= chooseBaitUIOpenWaitEndTime) + Cv2.FindContours(canny, out Point[][] contours, out _, RetrievalModes.External, ContourApproximationModes.ApproxSimple, null); + contours = contours + .Where(c => { - logger.LogWarning("没有找到目标鱼饵"); - input.Keyboard.KeyPress(VK.VK_ESCAPE); + Rect r = Cv2.BoundingRect(c); + if (r.Width < 0.065 * imageRegion.Width * 0.80) // 剔除太小的 + { + return false; + } + if (r.Height == 0) + { + return false; + } + return Math.Abs((float)r.Width / r.Height - 0.81) < 0.05; // 按形状筛选 + }).ToArray(); + IEnumerable boxes = contours.Select(Cv2.BoundingRect); + + foreach (Rect box in boxes) + { + using ImageRegion resRa = singleRowGrid.DeriveCrop(box); + using Mat img125 = resRa.SrcMat.GetGridIcon(); + (string predName, _) = GridIconsAccuracyTestTask.Infer(img125, this.session, this.prototypes); + if (predName == blackboard.selectedBait.GetDescription()) + { + resRa.Click(); + blackboard.Sleep(700); + // 可能重复点击,所以固定界面点击下 + imageRegion.ClickTo((int)(imageRegion.Width * 0.675), (int)(imageRegion.Height / 3d)); + blackboard.Sleep(200); + // 点击确定 + using var ra = imageRegion.Find(new RecognitionObject + { + Name = "BtnWhiteConfirm", + RecognitionType = RecognitionTypes.TemplateMatch, + TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "btn_white_confirm.png", systemInfo), + Use3Channels = true + }.InitTemplate()); + if (ra.IsExist()) + { + ra.Click(); + } blackboard.chooseBaitUIOpening = false; logger.LogInformation("退出换饵界面"); + blackboard.Sleep(500); // 等待界面切换 - blackboard.chooseBaitFailures.Add(blackboard.selectedBaitName); - if (blackboard.chooseBaitFailures.Count(f => f == blackboard.selectedBaitName) >= MAX_FAILED_TIMES) - { - logger.LogWarning($"本次将忽略{BaitType.FromName(blackboard.selectedBaitName).ChineseName}"); - } - - blackboard.selectedBaitName = string.Empty; - - return BehaviourStatus.Failed; + return BehaviourStatus.Succeeded; } - else + } + + if (timeProvider.GetLocalNow() >= chooseBaitUIOpenWaitEndTime) + { + logger.LogWarning("没有找到目标鱼饵"); + input.Keyboard.KeyPress(VK.VK_ESCAPE); + blackboard.chooseBaitUIOpening = false; + logger.LogInformation("退出换饵界面"); + + blackboard.chooseBaitFailures.Add(blackboard.selectedBait.Value); + if (blackboard.chooseBaitFailures.Count(f => f == blackboard.selectedBait) >= MAX_FAILED_TIMES) { - return BehaviourStatus.Running; + logger.LogWarning($"本次将忽略{blackboard.selectedBait.GetDescription()}"); } + + blackboard.selectedBait = null; + + return BehaviourStatus.Failed; } else { - resRa.Click(); - blackboard.Sleep(700); - // 可能重复点击,所以固定界面点击下 - imageRegion.ClickTo((int)(imageRegion.Width * 0.675), (int)(imageRegion.Height / 3d)); - blackboard.Sleep(200); - // 点击确定 - using var ra = imageRegion.Find(new RecognitionObject - { - Name = "BtnWhiteConfirm", - RecognitionType = RecognitionTypes.TemplateMatch, - TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "btn_white_confirm.png", systemInfo), - Use3Channels = true - }.InitTemplate()); - if (ra.IsExist()) - { - ra.Click(); - } - blackboard.chooseBaitUIOpening = false; - logger.LogInformation("退出换饵界面"); - blackboard.Sleep(500); // 等待界面切换 + return BehaviourStatus.Running; } - - return BehaviourStatus.Succeeded; } } @@ -374,10 +396,10 @@ namespace BetterGenshinImpact.GameTask.AutoFishing // 找到落点最近的鱼 currentFish = null; - string[] ignoredBaits = blackboard.throwRodNoBaitFishFailures.GroupBy(f => f).Where(g => g.Count() >= MAX_NO_BAIT_FISH_TIMES).Select(g => g.Key).ToArray(); + BaitType[] ignoredBaits = blackboard.throwRodNoBaitFishFailures.GroupBy(f => f).Where(g => g.Count() >= MAX_NO_BAIT_FISH_TIMES).Select(g => g.Key).ToArray(); var list = fishpond.Fishes - .Where(f => !ignoredBaits.Contains(f.FishType.BaitName)) // 不能是已经失败两次的饵; - .Where(f => f.FishType.BaitName == blackboard.selectedBaitName).OrderByDescending(f => f.Confidence) + .Where(f => !ignoredBaits.Contains(f.FishType.BaitType)) // 不能是已经失败两次的饵; + .Where(f => f.FishType.BaitType == blackboard.selectedBait).OrderByDescending(f => f.Confidence) .ToList(); if (list.Count > 0) { @@ -393,13 +415,17 @@ namespace BetterGenshinImpact.GameTask.AutoFishing { // 没有找到鱼饵适用鱼,重新选择鱼饵 blackboard.throwRodNoBaitFish = true; - blackboard.throwRodNoBaitFishFailures.Add(blackboard.selectedBaitName); - if (blackboard.throwRodNoBaitFishFailures.Count(f => f == blackboard.selectedBaitName) >= MAX_NO_BAIT_FISH_TIMES) + if (blackboard.selectedBait == null) { - logger.LogWarning($"本次将忽略{BaitType.FromName(blackboard.selectedBaitName).ChineseName}"); + throw new NullReferenceException(); + } + blackboard.throwRodNoBaitFishFailures.Add(blackboard.selectedBait.Value); + if (blackboard.throwRodNoBaitFishFailures.Count(f => f == blackboard.selectedBait) >= MAX_NO_BAIT_FISH_TIMES) + { + logger.LogWarning("本次将忽略{bait}", blackboard.selectedBait.GetDescription()); } - blackboard.selectedBaitName = string.Empty; + blackboard.selectedBait = null; logger.LogInformation("没有找到鱼饵适用鱼"); input.Mouse.LeftButtonUp(); blackboard.Sleep(2000); diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Blackboard.cs b/BetterGenshinImpact/GameTask/AutoFishing/Blackboard.cs index f460772f..1e17deaa 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/Blackboard.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/Blackboard.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using BetterGenshinImpact.Core.Recognition.ONNX; using BetterGenshinImpact.GameTask.AutoFishing.Assets; @@ -18,9 +18,9 @@ namespace BetterGenshinImpact.GameTask.AutoFishing public bool abort = false; /// - /// 已选择的鱼饵名 + /// 已选择的鱼饵类型 /// - public string selectedBaitName = string.Empty; + public BaitType? selectedBait = null; /// /// 鱼塘 @@ -44,9 +44,9 @@ namespace BetterGenshinImpact.GameTask.AutoFishing /// /// 抛竿无目标鱼失败列表 - /// 失败一次就加入一次鱼饵名,列表中同名鱼饵的数量代表该种失败了几次 + /// 失败一次就加入一次鱼饵类型,列表中同名鱼饵的数量代表该种失败了几次 /// - public List throwRodNoBaitFishFailures = new List(); + public List throwRodNoBaitFishFailures = new List(); /// /// 拉条位置的识别框 @@ -61,9 +61,9 @@ namespace BetterGenshinImpact.GameTask.AutoFishing /// /// 选鱼饵失败列表 - /// 失败一次就加入一次鱼饵名,列表中同名鱼饵的数量代表该种失败了几次 + /// 失败一次就加入一次鱼饵类型,列表中同名鱼饵的数量代表该种失败了几次 /// - public List chooseBaitFailures = new List(); + public List chooseBaitFailures = new List(); /// /// 镜头俯仰是否被行为重置 @@ -104,12 +104,12 @@ namespace BetterGenshinImpact.GameTask.AutoFishing { abort = false; throwRodNoTargetTimes = 0; - throwRodNoBaitFishFailures = new List(); + throwRodNoBaitFishFailures = new List(); fishBoxRect = default; chooseBaitUIOpening = false; - chooseBaitFailures = new List(); + chooseBaitFailures = new List(); pitchReset = true; - selectedBaitName = string.Empty; + selectedBait = null; } } } diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Model/BaitType.cs b/BetterGenshinImpact/GameTask/AutoFishing/Model/BaitType.cs index 16cfdc9e..3e269cc8 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/Model/BaitType.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/Model/BaitType.cs @@ -1,54 +1,25 @@ -using System.Collections.Generic; +using System.ComponentModel; namespace BetterGenshinImpact.GameTask.AutoFishing.Model; -public class BaitType +public enum BaitType { - - public static readonly BaitType FruitPasteBait = new("fruit paste bait", "果酿饵"); - public static readonly BaitType RedrotBait = new("redrot bait", "赤糜饵"); - public static readonly BaitType FalseWormBait = new("false worm bait", "蠕虫假饵"); - public static readonly BaitType FakeFlyBait = new("fake fly bait", "飞蝇假饵"); - public static readonly BaitType SugardewBait = new("sugardew bait", "甘露饵"); - public static readonly BaitType SourBait = new("sour bait", "酸桔饵"); - public static readonly BaitType FlashingMaintenanceMekBait = new("flashing maintenance mek bait", "维护机关频闪诱饵"); - public static readonly BaitType SpinelgrainBait = new("spinelgrain bait", "澄晶果粒饵"); - public static readonly BaitType EmberglowBait = new("emberglow bait", "温火饵"); - - public static IEnumerable Values - { - get - { - yield return FruitPasteBait; - yield return RedrotBait; - yield return FalseWormBait; - yield return FakeFlyBait; - yield return SugardewBait; - yield return SourBait; - yield return FlashingMaintenanceMekBait; - yield return SpinelgrainBait; - yield return EmberglowBait; - } - } - public string Name { get; private set; } - public string ChineseName { get; private set; } - - private BaitType(string name, string chineseName) - { - Name = name; - ChineseName = chineseName; - } - - public static BaitType FromName(string name) - { - foreach (var type in Values) - { - if (type.Name == name) - { - return type; - } - } - - throw new KeyNotFoundException($"BaitType {name} not found"); - } + [Description("果酿饵")] + FruitPasteBait, + [Description("赤糜饵")] + RedrotBait, + [Description("蠕虫假饵")] + FalseWormBait, + [Description("飞蝇假饵")] + FakeFlyBait, + [Description("甘露饵")] + SugardewBait, + [Description("酸桔饵")] + SourBait, + [Description("维护机关频闪诱饵")] + FlashingMaintenanceMekBait, + [Description("澄晶果粒饵")] + SpinelgrainBait, + [Description("温火饵")] + EmberglowBait } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/AutoFishing/Model/BigFishType.cs b/BetterGenshinImpact/GameTask/AutoFishing/Model/BigFishType.cs index fdbab99d..6cf0f561 100644 --- a/BetterGenshinImpact/GameTask/AutoFishing/Model/BigFishType.cs +++ b/BetterGenshinImpact/GameTask/AutoFishing/Model/BigFishType.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace BetterGenshinImpact.GameTask.AutoFishing.Model; @@ -9,27 +9,27 @@ namespace BetterGenshinImpact.GameTask.AutoFishing.Model; /// public class BigFishType { - public static readonly BigFishType Medaka = new("medaka", "fruit paste bait", "花鳉", 0); - public static readonly BigFishType LargeMedaka = new("large medaka", "fruit paste bait", "大花鳉", 1); - public static readonly BigFishType Stickleback = new("stickleback", "redrot bait", "棘鱼", 2); - public static readonly BigFishType Koi = new("koi", "fake fly bait", "假龙", 3); - public static readonly BigFishType KoiHead = new("koi head", "fake fly bait", "假龙头", 3); - public static readonly BigFishType Butterflyfish = new("butterflyfish", "false worm bait", "蝶鱼", 4); - public static readonly BigFishType Pufferfish = new("pufferfish", "fake fly bait", "炮鲀", 5); + public static readonly BigFishType Medaka = new("medaka", BaitType.FruitPasteBait, "花鳉", 0); + public static readonly BigFishType LargeMedaka = new("large medaka", BaitType.FruitPasteBait, "大花鳉", 1); + public static readonly BigFishType Stickleback = new("stickleback", BaitType.RedrotBait, "棘鱼", 2); + public static readonly BigFishType Koi = new("koi", BaitType.FakeFlyBait, "假龙", 3); + public static readonly BigFishType KoiHead = new("koi head", BaitType.FakeFlyBait, "假龙头", 3); + public static readonly BigFishType Butterflyfish = new("butterflyfish", BaitType.FalseWormBait, "蝶鱼", 4); + public static readonly BigFishType Pufferfish = new("pufferfish", BaitType.FakeFlyBait, "炮鲀", 5); - public static readonly BigFishType Ray = new("ray", "fake fly bait", "鳐", 6); + public static readonly BigFishType Ray = new("ray", BaitType.FakeFlyBait, "鳐", 6); - // public static readonly BigFishType FormaloRay = new("formalo ray", "fake fly bait", "佛玛洛鳐"); - // public static readonly BigFishType DivdaRay = new("divda ray", "fake fly bait", "迪芙妲鳐"); - public static readonly BigFishType Angler = new("angler", "sugardew bait", "角鲀", 7); - public static readonly BigFishType AxeMarlin = new("axe marlin", "sugardew bait", "斧枪鱼", 8); - public static readonly BigFishType HeartfeatherBass = new("heartfeather bass", "sour bait", "心羽鲈", 9); - public static readonly BigFishType MaintenanceMek = new("maintenance mek", "flashing maintenance mek bait", "维护机关", 10); - public static readonly BigFishType Unihornfish = new("unihornfish", "spinelgrain bait", "独角鱼", 10); - public static readonly BigFishType Sunfish = new("sunfish", "spinelgrain bait", "翻车鲀", 7); - public static readonly BigFishType Rapidfish = new("rapidfish", "spinelgrain bait", "斗士急流鱼", 9); - public static readonly BigFishType PhonyUnihornfish = new("phony unihornfish", "emberglow bait", "燃素独角鱼", 10); - public static readonly BigFishType MagmaRapidfish = new("magma rapidfish", "emberglow bait", "炽岩斗士急流鱼", 9); + // public static readonly BigFishType FormaloRay = new("formalo ray", "飞蝇假饵", "佛玛洛鳐"); + // public static readonly BigFishType DivdaRay = new("divda ray", "飞蝇假饵", "迪芙妲鳐"); + public static readonly BigFishType Angler = new("angler", BaitType.SugardewBait, "角鲀", 7); + public static readonly BigFishType AxeMarlin = new("axe marlin", BaitType.SugardewBait, "斧枪鱼", 8); + public static readonly BigFishType HeartfeatherBass = new("heartfeather bass", BaitType.SourBait, "心羽鲈", 9); + public static readonly BigFishType MaintenanceMek = new("maintenance mek", BaitType.FlashingMaintenanceMekBait, "维护机关", 10); + public static readonly BigFishType Unihornfish = new("unihornfish", BaitType.SpinelgrainBait, "独角鱼", 10); + public static readonly BigFishType Sunfish = new("sunfish", BaitType.SpinelgrainBait, "翻车鲀", 7); + public static readonly BigFishType Rapidfish = new("rapidfish", BaitType.SpinelgrainBait, "斗士急流鱼", 9); + public static readonly BigFishType PhonyUnihornfish = new("phony unihornfish", BaitType.EmberglowBait, "燃素独角鱼", 10); + public static readonly BigFishType MagmaRapidfish = new("magma rapidfish", BaitType.EmberglowBait, "炽岩斗士急流鱼", 9); public static IEnumerable Values @@ -59,15 +59,15 @@ public class BigFishType } public string Name { get; private set; } - public string BaitName { get; private set; } + public BaitType BaitType { get; private set; } public string ChineseName { get; private set; } public int NetIndex { get; private set; } - private BigFishType(string name, string baitName, string chineseName, int netIndex) + private BigFishType(string name, BaitType baitType, string chineseName, int netIndex) { Name = name; - BaitName = baitName; + BaitType = baitType; ChineseName = chineseName; NetIndex = netIndex; } diff --git a/BetterGenshinImpact/GameTask/AutoStygianOnslaught/AutoStygianOnslaughtTask.cs b/BetterGenshinImpact/GameTask/AutoStygianOnslaught/AutoStygianOnslaughtTask.cs index 29d64a85..76472706 100644 --- a/BetterGenshinImpact/GameTask/AutoStygianOnslaught/AutoStygianOnslaughtTask.cs +++ b/BetterGenshinImpact/GameTask/AutoStygianOnslaught/AutoStygianOnslaughtTask.cs @@ -609,7 +609,7 @@ public class AutoStygianOnslaughtTask : ISoloTask star = 4; } - await new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(star, javaScript: null, maxNumToCheck: null, recognitionFailurePolicy: null)).Start(_ct); + await new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(star, javaScript: null, artifactSetFilter: null, maxNumToCheck: null, recognitionFailurePolicy: null)).Start(_ct); } diff --git a/BetterGenshinImpact/GameTask/GetGridIcons/GetGridIconsTask.cs b/BetterGenshinImpact/GameTask/GetGridIcons/GetGridIconsTask.cs index 3afeb078..3ac3678d 100644 --- a/BetterGenshinImpact/GameTask/GetGridIcons/GetGridIconsTask.cs +++ b/BetterGenshinImpact/GameTask/GetGridIcons/GetGridIconsTask.cs @@ -3,6 +3,7 @@ using BetterGenshinImpact.Core.Simulator; using BetterGenshinImpact.GameTask.AutoArtifactSalvage; using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Common.Job; +using BetterGenshinImpact.GameTask.Model; using BetterGenshinImpact.GameTask.Model.Area; using BetterGenshinImpact.GameTask.Model.GameUI; using BetterGenshinImpact.Helpers.Extensions; @@ -198,13 +199,8 @@ public class GetGridIconsTask : ISoloTask { using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) { - double scale = TaskContext.Instance().SystemInfo.AssetScale; - double width = 60; - double height = 60; // 宽高缩放似乎不一致,似乎在2.05:2.15之间,但不知道怎么测定 - Rect iconRect = new Rect((int)(itemRegion.Width / 2 - 237 * scale - width / 2), (int)(itemRegion.Height / 2 - height / 2), (int)width, (int)height); - Mat crop = itemRegion.SrcMat.SubMat(iconRect); - using Mat resize = crop.Resize(new Size(125, 125)); - resize.ToBitmap().Save(fs, System.Drawing.Imaging.ImageFormat.Png); + using Mat img125 = CropResizeArtifactSetFilterGridIcon(itemRegion); + img125.ToBitmap().Save(fs, System.Drawing.Imaging.ImageFormat.Png); } logger.LogInformation("图片保存成功:{Text}", fileName); } @@ -230,6 +226,16 @@ public class GetGridIconsTask : ISoloTask } } + internal static Mat CropResizeArtifactSetFilterGridIcon(ImageRegion itemRegion, ISystemInfo? systemInfo = null) + { + double scale = (systemInfo ?? TaskContext.Instance().SystemInfo).AssetScale; + double width = 60; + double height = 60; // 宽高缩放似乎不一致,似乎在2.05:2.15之间,但不知道怎么测定 + Rect iconRect = new Rect((int)(itemRegion.Width / 2 - 237 * scale - width / 2), (int)(itemRegion.Height / 2 - height / 2), (int)width, (int)height); + Mat crop = itemRegion.SrcMat.SubMat(iconRect); + return crop.Resize(new Size(125, 125)); + } + /// /// OCR检测★字符很不稳定,因此用cv /// 非常简陋的色彩检测,请传入聚焦的图像,勿带入可能的干扰 diff --git a/BetterGenshinImpact/GameTask/GetGridIcons/GridIconsAccuracyTestTask.cs b/BetterGenshinImpact/GameTask/GetGridIcons/GridIconsAccuracyTestTask.cs index 8b97f248..63101ddd 100644 --- a/BetterGenshinImpact/GameTask/GetGridIcons/GridIconsAccuracyTestTask.cs +++ b/BetterGenshinImpact/GameTask/GetGridIcons/GridIconsAccuracyTestTask.cs @@ -111,7 +111,6 @@ public class GridIconsAccuracyTestTask : ISoloTask { itemRegion.Click(); Task task1 = Delay(300, ct); - var sadf = task1.Status; // 用模型推理得到的结果 Task<(string, int)> task2 = Task.Run(() => @@ -161,7 +160,7 @@ public class GridIconsAccuracyTestTask : ISoloTask /// /// /// - /// + /// (预测名称, 预测星级) /// public static (string, int) Infer(Mat mat, InferenceSession session, Dictionary prototypes) { diff --git a/BetterGenshinImpact/GameTask/Model/GameUI/GridScreen.cs b/BetterGenshinImpact/GameTask/Model/GameUI/GridScreen.cs index ae5cb74d..f09d1456 100644 --- a/BetterGenshinImpact/GameTask/Model/GameUI/GridScreen.cs +++ b/BetterGenshinImpact/GameTask/Model/GameUI/GridScreen.cs @@ -215,7 +215,7 @@ namespace BetterGenshinImpact.GameTask.Model.GameUI { return false; } - return Math.Abs((float)r.Width / r.Height - 0.8) < 0.05; // 按形状筛选 + return Math.Abs((float)r.Width / r.Height - 0.81) < 0.05; // 按形状筛选 }).ToArray(); IEnumerable boxes = contours.Select(Cv2.BoundingRect); diff --git a/BetterGenshinImpact/Helpers/Extensions/EnumExtensions.cs b/BetterGenshinImpact/Helpers/Extensions/EnumExtensions.cs index 6e5d5cb5..6a4ea194 100644 --- a/BetterGenshinImpact/Helpers/Extensions/EnumExtensions.cs +++ b/BetterGenshinImpact/Helpers/Extensions/EnumExtensions.cs @@ -1,8 +1,10 @@ +using BetterGenshinImpact.Model; using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using BetterGenshinImpact.Model; +using System.Reflection; namespace BetterGenshinImpact.Helpers.Extensions; @@ -18,6 +20,33 @@ public static class EnumExtensions ?.Description ?? value.ToString(); } + public static bool TryGetEnumValueFromDescription(this string description, [NotNullWhen(true)] out T? result) where T : struct, Enum + { + result = null; + if (string.IsNullOrEmpty(description)) + return false; + + var type = typeof(T); + foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static)) + { + if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) + is DescriptionAttribute attribute) + { + if (attribute.Description.Equals(description, StringComparison.OrdinalIgnoreCase)) + { + var value = field.GetValue(null); + if (value is T enumValue) + { + result = enumValue; + return true; + } + return false; + } + } + } + return false; + } + public static int GetOrder(this Enum value) { return value.GetType() diff --git a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml index 08aed9eb..db677611 100644 --- a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml @@ -2377,6 +2377,38 @@ Text="{Binding Config.AutoArtifactSalvageConfig.JavaScript, Mode=TwoWay}" TextWrapping="Wrap" Cursor="IBeam" /> + + + + + + + + + + + 按套装筛选 + + + 利用游戏自带的筛选功能先行筛选 + + 一般填写套装内生之花名,可填入多个名称;留空则不用 + + + diff --git a/BetterGenshinImpact/View/Windows/OcrDialog.xaml.cs b/BetterGenshinImpact/View/Windows/OcrDialog.xaml.cs index 7b14f09d..8b32bc18 100644 --- a/BetterGenshinImpact/View/Windows/OcrDialog.xaml.cs +++ b/BetterGenshinImpact/View/Windows/OcrDialog.xaml.cs @@ -28,7 +28,7 @@ public partial class OcrDialog this.widthRatio = widthRatio; this.heightRatio = heightRatio; this.javaScript = javaScript; - this.autoArtifactSalvageTask = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, new CultureInfo(TaskContext.Instance().Config.OtherConfig.GameCultureInfoName))); + this.autoArtifactSalvageTask = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, null, new CultureInfo(TaskContext.Instance().Config.OtherConfig.GameCultureInfoName))); InitializeComponent(); diff --git a/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs index d9203245..7ed038bd 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs @@ -584,7 +584,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel Config.HotKeyConfig.Test1HotkeyType, (_, _) => { - Task.Run(async () => { await new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(star: 4, null, null, null)).Start(new CancellationToken()); }); + Task.Run(async () => { await new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(star: 4, null, null, null, null)).Start(new CancellationToken()); }); } )); diff --git a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs index 2af3dea0..96bd4c4f 100644 --- a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs @@ -537,6 +537,7 @@ public partial class TaskSettingsPageViewModel : ViewModel .RunSoloTaskAsync(new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam( int.Parse(Config.AutoArtifactSalvageConfig.MaxArtifactStar), Config.AutoArtifactSalvageConfig.JavaScript, + Config.AutoArtifactSalvageConfig.ArtifactSetFilter, Config.AutoArtifactSalvageConfig.MaxNumToCheck, Config.AutoArtifactSalvageConfig.RecognitionFailurePolicy ))); diff --git a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoArtifactSalvageTests/AutoArtifactSalvageTaskTests.cs b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoArtifactSalvageTests/AutoArtifactSalvageTaskTests.cs index b89248b5..bc450699 100644 --- a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoArtifactSalvageTests/AutoArtifactSalvageTaskTests.cs +++ b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoArtifactSalvageTests/AutoArtifactSalvageTaskTests.cs @@ -98,7 +98,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoArtifactSalvageTests CultureInfo cultureInfo = new CultureInfo("zh-Hans"); // - AutoArtifactSalvageTask sut = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, cultureInfo, this.stringLocalizer), new FakeLogger()); + AutoArtifactSalvageTask sut = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, null, cultureInfo, this.stringLocalizer), new FakeLogger()); string result = PaddleResultDic.GetOrAdd(screenshot, screenshot_ => { using Mat mat = new Mat(@$"..\..\..\Assets\AutoArtifactSalvage\{screenshot_}"); @@ -203,7 +203,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoArtifactSalvageTests */ // - AutoArtifactSalvageTask sut = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, cultureInfo, this.stringLocalizer), new FakeLogger()); + AutoArtifactSalvageTask sut = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, null, cultureInfo, this.stringLocalizer), new FakeLogger()); ArtifactStat result = sut.GetArtifactStat(mat, paddle.Get(cultureInfo.Name), out string _); // @@ -237,7 +237,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoArtifactSalvageTests CultureInfo cultureInfo = new CultureInfo("zh-Hans"); // - AutoArtifactSalvageTask sut = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, cultureInfo, this.stringLocalizer), new FakeLogger()); + AutoArtifactSalvageTask sut = new AutoArtifactSalvageTask(new AutoArtifactSalvageTaskParam(5, null, null, null, null, cultureInfo, this.stringLocalizer), new FakeLogger()); ArtifactStat artifact = sut.GetArtifactStat(mat, paddle.Get(), out string _); bool result = IsMatchJavaScript(artifact, js); diff --git a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ChooseBait.cs b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ChooseBait.cs index cf70aaa8..d5cfa27d 100644 --- a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ChooseBait.cs +++ b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ChooseBait.cs @@ -1,4 +1,4 @@ -using BehaviourTree; +using BehaviourTree; using BetterGenshinImpact.GameTask.AutoFishing; using BetterGenshinImpact.GameTask.AutoFishing.Model; using BetterGenshinImpact.GameTask.Model.Area; @@ -17,7 +17,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests { [Theory] [InlineData(@"20250225101300361_ChooseBait_Succeeded.png", new string[] { "medaka", "butterflyfish", "butterflyfish", "pufferfish" })] - [InlineData(@"20250226161354285_ChooseBait_Succeeded.png", new string[] { "medaka", "medaka" })] + [InlineData(@"20250226161354285_ChooseBait_Succeeded.png", new string[] { "medaka", "medaka" })] // todo 更新用例 [InlineData(@"202503160917566615@900p.png", new string[] { "pufferfish" })] /// /// 测试各种选取鱼饵,结果为成功 @@ -35,7 +35,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests }; // - ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator()); + ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), this.session, this.prototypes); BehaviourStatus actual = sut.Tick(imageRegion); // @@ -69,11 +69,11 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests FakeTimeProvider fakeTimeProvider = new FakeTimeProvider(dateTime); // - ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), fakeTimeProvider); + ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), this.session, this.prototypes, fakeTimeProvider); BehaviourStatus actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.True(blackboard.chooseBaitUIOpening); Assert.Equal(BehaviourStatus.Running, actual); @@ -84,7 +84,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.False(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.NotNull(blackboard.selectedBait); Assert.True(blackboard.chooseBaitUIOpening); Assert.Equal(BehaviourStatus.Running, actual); @@ -95,7 +95,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.False(blackboard.chooseBaitUIOpening); Assert.Equal(BehaviourStatus.Failed, actual); } @@ -124,15 +124,15 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests #region 第1次失败 // - ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), fakeTimeProvider); + ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), this.session, this.prototypes, fakeTimeProvider); BehaviourStatus actual = sut.Tick(imageRegion); fakeTimeProvider.SetUtcNow(dateTime.AddSeconds(3)); actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Single(blackboard.chooseBaitFailures.Where(f => f == "fake fly bait")); + Assert.Single(blackboard.chooseBaitFailures.Where(f => f == BaitType.FakeFlyBait)); #endregion #region 第2次失败 @@ -146,9 +146,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == "fake fly bait").Count()); + Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == BaitType.FakeFlyBait).Count()); Assert.False(blackboard.abort); #endregion @@ -165,9 +165,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Single(blackboard.chooseBaitFailures.Where(f => f == "spinelgrain bait")); + Assert.Single(blackboard.chooseBaitFailures.Where(f => f == BaitType.SpinelgrainBait)); #endregion #region sunfish受到遮挡,medaka再次出现,第4次成功,并钓起medaka @@ -183,9 +183,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.False(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.NotNull(blackboard.selectedBait); // todo 更新用例 Assert.Equal(BehaviourStatus.Succeeded, actual); - Assert.Single(blackboard.chooseBaitFailures.Where(f => f == "spinelgrain bait")); + Assert.Single(blackboard.chooseBaitFailures.Where(f => f == BaitType.SpinelgrainBait)); #endregion #region sunfish再次出现,第5次失败 @@ -201,9 +201,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == "spinelgrain bait").Count()); + Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == BaitType.SpinelgrainBait).Count()); #endregion } @@ -230,15 +230,15 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests #region 第1次失败 // - ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), fakeTimeProvider); + ChooseBait sut = new ChooseBait("-", blackboard, new FakeLogger(), false, systemInfo, new FakeInputSimulator(), this.session, this.prototypes, fakeTimeProvider); BehaviourStatus actual = sut.Tick(imageRegion); fakeTimeProvider.SetUtcNow(dateTime.AddSeconds(3)); actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Single(blackboard.chooseBaitFailures.Where(f => f == "fake fly bait")); + Assert.Single(blackboard.chooseBaitFailures.Where(f => f == BaitType.FakeFlyBait)); #endregion #region koi受到遮挡,第2次失败 @@ -254,9 +254,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Single(blackboard.chooseBaitFailures.Where(f => f == "spinelgrain bait")); + Assert.Single(blackboard.chooseBaitFailures.Where(f => f == BaitType.SpinelgrainBait)); Assert.False(blackboard.abort); #endregion @@ -273,9 +273,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == "fake fly bait").Count()); + Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == BaitType.FakeFlyBait).Count()); #endregion #region 第4次失败 @@ -291,9 +291,9 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests actual = sut.Tick(imageRegion); // - Assert.True(String.IsNullOrEmpty(blackboard.selectedBaitName)); + Assert.Null(blackboard.selectedBait); Assert.Equal(BehaviourStatus.Failed, actual); - Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == "spinelgrain bait").Count()); + Assert.Equal(2, blackboard.chooseBaitFailures.Where(f => f == BaitType.SpinelgrainBait).Count()); #endregion } } diff --git a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.GetFishpond.cs b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.GetFishpond.cs index 80a9f460..c0615176 100644 --- a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.GetFishpond.cs +++ b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.GetFishpond.cs @@ -1,8 +1,9 @@ -using BetterGenshinImpact.GameTask.AutoFishing; +using BetterGenshinImpact.GameTask.AutoFishing; using BehaviourTree; using BetterGenshinImpact.GameTask.Model.Area; using Microsoft.Extensions.Time.Testing; using OpenCvSharp; +using BetterGenshinImpact.GameTask.AutoFishing.Model; namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests { @@ -38,10 +39,10 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests } [Theory] - [InlineData("20250225101257889_GetFishpond_Succeeded.png", new string[] { "fruit paste bait", "fruit paste bait", "redrot bait", "redrot bait" }, new string[] { "false worm bait", "false worm bait", "fake fly bait", "fake fly bait" })] + [InlineData("20250225101257889_GetFishpond_Succeeded.png", new BaitType[] { BaitType.FruitPasteBait, BaitType.FruitPasteBait, BaitType.RedrotBait, BaitType.RedrotBait }, new BaitType[] { BaitType.FalseWormBait, BaitType.FalseWormBait, BaitType.FakeFlyBait, BaitType.FakeFlyBait })] /// 测试鱼的鱼饵均在失败列表中且被忽略,结果为运行中 /// - public void GetFishpondTest_AllIgnored_ShouldBeRunning(string screenshot1080p, IEnumerable chooseBaitfailures, IEnumerable throwRodNoTargetFishfailures) + public void GetFishpondTest_AllIgnored_ShouldBeRunning(string screenshot1080p, IEnumerable chooseBaitfailures, IEnumerable throwRodNoTargetFishfailures) { // Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}"); diff --git a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ThrowRod.cs b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ThrowRod.cs index 0850d817..5c0bc914 100644 --- a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ThrowRod.cs +++ b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ThrowRod.cs @@ -1,4 +1,4 @@ -using BehaviourTree; +using BehaviourTree; using BetterGenshinImpact.GameTask.AutoFishing; using BetterGenshinImpact.GameTask.Model.Area.Converter; using BetterGenshinImpact.GameTask.Model.Area; @@ -6,18 +6,19 @@ using Microsoft.Extensions.Time.Testing; using OpenCvSharp; using BehaviourTree.Composites; using BehaviourTree.FluentBuilder; +using BetterGenshinImpact.GameTask.AutoFishing.Model; namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests { public partial class BehavioursTests { [Theory] - [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "false worm bait")] - [InlineData(@"20250226162217468_ThrowRod_Succeeded.png", "fruit paste bait")] + [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", BaitType.FalseWormBait)] + [InlineData(@"20250226162217468_ThrowRod_Succeeded.png", BaitType.FruitPasteBait)] /// /// 测试各种抛竿,结果为成功 /// - public void ThrowRodTest_VariousFish_ShouldSuccess(string screenshot1080p, string selectedBaitName) + public void ThrowRodTest_VariousFish_ShouldSuccess(string screenshot1080p, BaitType selectedBait) { // Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}"); @@ -25,7 +26,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests var blackboard = new Blackboard(Predictor, sleep: i => { }) { - selectedBaitName = selectedBaitName + selectedBait = selectedBait }; FakeTimeProvider fakeTimeProvider = new FakeTimeProvider(); @@ -40,12 +41,12 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests } [Theory] - [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "redrot bait")] - [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "fake fly bait")] + [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", BaitType.RedrotBait)] + [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", BaitType.FakeFlyBait)] /// /// 测试各种抛竿,未满足HutaoFisher判定,结果为运行中 /// - public void ThrowRodTest_VariousFish_ShouldFail(string screenshot1080p, string selectedBaitName) + public void ThrowRodTest_VariousFish_ShouldFail(string screenshot1080p, BaitType selectedBait) { // Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}"); @@ -53,7 +54,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests var blackboard = new Blackboard(Predictor, sleep: i => { }) { - selectedBaitName = selectedBaitName + selectedBait = selectedBait }; FakeTimeProvider fakeTimeProvider = new FakeTimeProvider(); @@ -68,11 +69,11 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests } [Theory] - [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "flashing maintenance mek bait")] + [InlineData(@"20250225101304534_ThrowRod_Succeeded.png", BaitType.FlashingMaintenanceMekBait)] /// /// 测试各种抛竿,无鱼饵适用鱼,结果为失败 /// - public void ThrowRodTest_NoBaitFish_ShouldFail(string screenshot1080p, string selectedBaitName) + public void ThrowRodTest_NoBaitFish_ShouldFail(string screenshot1080p, BaitType selectedBait) { // Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}"); @@ -80,7 +81,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests var blackboard = new Blackboard(Predictor, sleep: i => { }) { - selectedBaitName = selectedBaitName + selectedBait = selectedBait }; FakeTimeProvider fakeTimeProvider = new FakeTimeProvider(); @@ -119,7 +120,7 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests var blackboard = new Blackboard(Predictor, sleep: i => { }) { - selectedBaitName = "fake fly bait" + selectedBait = GameTask.AutoFishing.Model.BaitType.FakeFlyBait }; // diff --git a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.cs b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.cs index a6fbfb1a..7507bee7 100644 --- a/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.cs +++ b/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.cs @@ -2,7 +2,9 @@ using BetterGenshinImpact.Core.Recognition.OCR; using BetterGenshinImpact.Core.Recognition.ONNX; using BetterGenshinImpact.GameTask.AutoFishing; using BetterGenshinImpact.UnitTest.CoreTests.RecognitionTests.OCRTests; +using BetterGenshinImpact.UnitTest.GameTaskTests.GetGridIconsTests; using Microsoft.Extensions.Localization; +using Microsoft.ML.OnnxRuntime; namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests { @@ -15,12 +17,17 @@ namespace BetterGenshinImpact.UnitTest.GameTaskTests.AutoFishingTests private readonly PaddleFixture paddle; private readonly IStringLocalizer stringLocalizer; + private readonly InferenceSession session; + private readonly Dictionary prototypes; - public BehavioursTests(PaddleFixture paddle, TorchFixture torch, LocalizationFixture localization) + + public BehavioursTests(PaddleFixture paddle, TorchFixture torch, LocalizationFixture localization, GridIconModelFixture iconModel) { this.paddle = paddle; this.useTorch = torch.UseTorch; this.stringLocalizer = localization.CreateStringLocalizer(); + this.session = iconModel.modelLoader.Value.session; + this.prototypes = iconModel.modelLoader.Value.prototypes; } private IOcrService OcrService => paddle.Get();