图标识别应用两则 (#2154)
@@ -14,6 +14,10 @@ public partial class AutoArtifactSalvageConfig : ObservableObject
|
||||
Output = hasATK && hasDEF;
|
||||
})(ArtifactStat);";
|
||||
|
||||
// JavaScript
|
||||
[ObservableProperty]
|
||||
private string _artifactSetFilter = "";
|
||||
|
||||
// 正则表达式
|
||||
[Obsolete]
|
||||
[ObservableProperty]
|
||||
|
||||
@@ -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<AutoArtifactSalvageTask>();
|
||||
@@ -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<string, float[]> 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("筛选完毕,请复查并手动分解");
|
||||
}
|
||||
|
||||
@@ -9,16 +9,18 @@ namespace BetterGenshinImpact.GameTask.AutoArtifactSalvage
|
||||
{
|
||||
public class AutoArtifactSalvageTaskParam : BaseTaskParam<AutoArtifactSalvageTask>
|
||||
{
|
||||
public AutoArtifactSalvageTaskParam(int star, string? javaScript, int? maxNumToCheck, RecognitionFailurePolicy? recognitionFailurePolicy, CultureInfo? cultureInfo = null, IStringLocalizer<AutoArtifactSalvageTask>? stringLocalizer = null) : base(cultureInfo, stringLocalizer)
|
||||
public AutoArtifactSalvageTaskParam(int star, string? javaScript, string? artifactSetFilter, int? maxNumToCheck, RecognitionFailurePolicy? recognitionFailurePolicy, CultureInfo? cultureInfo = null, IStringLocalizer<AutoArtifactSalvageTask>? 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; }
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@@ -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<string, float[]> 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<string, float[]> 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<string, float[]> 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;
|
||||
|
||||
|
||||
@@ -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<string, float[]> prototypes;
|
||||
private readonly Blackboard blackboard;
|
||||
private readonly TimeProvider timeProvider;
|
||||
private DateTimeOffset? chooseBaitUIOpenWaitEndTime; // 等待选鱼饵界面出现并尝试找鱼饵的结束时间
|
||||
@@ -110,11 +116,13 @@ namespace BetterGenshinImpact.GameTask.AutoFishing
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="autoFishingTrigger"></param>
|
||||
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<string, float[]> 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<Rect> 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 已选择的鱼饵名
|
||||
/// 已选择的鱼饵类型
|
||||
/// </summary>
|
||||
public string selectedBaitName = string.Empty;
|
||||
public BaitType? selectedBait = null;
|
||||
|
||||
/// <summary>
|
||||
/// 鱼塘
|
||||
@@ -44,9 +44,9 @@ namespace BetterGenshinImpact.GameTask.AutoFishing
|
||||
|
||||
/// <summary>
|
||||
/// 抛竿无目标鱼失败列表
|
||||
/// 失败一次就加入一次鱼饵名,列表中同名鱼饵的数量代表该种失败了几次
|
||||
/// 失败一次就加入一次鱼饵类型,列表中同名鱼饵的数量代表该种失败了几次
|
||||
/// </summary>
|
||||
public List<string> throwRodNoBaitFishFailures = new List<string>();
|
||||
public List<BaitType> throwRodNoBaitFishFailures = new List<BaitType>();
|
||||
|
||||
/// <summary>
|
||||
/// 拉条位置的识别框
|
||||
@@ -61,9 +61,9 @@ namespace BetterGenshinImpact.GameTask.AutoFishing
|
||||
|
||||
/// <summary>
|
||||
/// 选鱼饵失败列表
|
||||
/// 失败一次就加入一次鱼饵名,列表中同名鱼饵的数量代表该种失败了几次
|
||||
/// 失败一次就加入一次鱼饵类型,列表中同名鱼饵的数量代表该种失败了几次
|
||||
/// </summary>
|
||||
public List<string> chooseBaitFailures = new List<string>();
|
||||
public List<BaitType> chooseBaitFailures = new List<BaitType>();
|
||||
|
||||
/// <summary>
|
||||
/// 镜头俯仰是否被行为重置
|
||||
@@ -104,12 +104,12 @@ namespace BetterGenshinImpact.GameTask.AutoFishing
|
||||
{
|
||||
abort = false;
|
||||
throwRodNoTargetTimes = 0;
|
||||
throwRodNoBaitFishFailures = new List<string>();
|
||||
throwRodNoBaitFishFailures = new List<BaitType>();
|
||||
fishBoxRect = default;
|
||||
chooseBaitUIOpening = false;
|
||||
chooseBaitFailures = new List<string>();
|
||||
chooseBaitFailures = new List<BaitType>();
|
||||
pitchReset = true;
|
||||
selectedBaitName = string.Empty;
|
||||
selectedBait = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BaitType> 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
|
||||
}
|
||||
@@ -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;
|
||||
/// </summary>
|
||||
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<BigFishType> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OCR检测★字符很不稳定,因此用cv
|
||||
/// 非常简陋的色彩检测,请传入聚焦的图像,勿带入可能的干扰
|
||||
|
||||
@@ -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
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="session"></param>
|
||||
/// <param name="prototypes"></param>
|
||||
/// <returns></returns>
|
||||
/// <returns>(预测名称, 预测星级)</returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static (string, int) Infer(Mat mat, InferenceSession session, Dictionary<string, float[]> prototypes)
|
||||
{
|
||||
|
||||
@@ -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<Rect> boxes = contours.Select(Cv2.BoundingRect);
|
||||
|
||||
@@ -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<T>(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()
|
||||
|
||||
@@ -2377,6 +2377,38 @@
|
||||
Text="{Binding Config.AutoArtifactSalvageConfig.JavaScript, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" Cursor="IBeam" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
TextWrapping="Wrap">
|
||||
按套装筛选
|
||||
</ui:TextBlock>
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
TextWrapping="Wrap">
|
||||
利用游戏自带的筛选功能先行筛选
|
||||
<LineBreak/>
|
||||
一般填写套装内生之花名,可填入多个名称;留空则不用
|
||||
</ui:TextBlock>
|
||||
<ui:TextBox Grid.Row="1"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="400"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.AutoArtifactSalvageConfig.ArtifactSetFilter, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" Cursor="IBeam" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()); });
|
||||
|
||||
}
|
||||
));
|
||||
|
||||
@@ -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
|
||||
)));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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" })]
|
||||
/// <summary>
|
||||
/// 测试各种选取鱼饵,结果为成功
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 })]
|
||||
/// 测试鱼的鱼饵均在失败列表中且被忽略,结果为运行中
|
||||
/// </summary>
|
||||
public void GetFishpondTest_AllIgnored_ShouldBeRunning(string screenshot1080p, IEnumerable<string> chooseBaitfailures, IEnumerable<string> throwRodNoTargetFishfailures)
|
||||
public void GetFishpondTest_AllIgnored_ShouldBeRunning(string screenshot1080p, IEnumerable<BaitType> chooseBaitfailures, IEnumerable<BaitType> throwRodNoTargetFishfailures)
|
||||
{
|
||||
//
|
||||
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}");
|
||||
|
||||
@@ -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)]
|
||||
/// <summary>
|
||||
/// 测试各种抛竿,结果为成功
|
||||
/// </summary>
|
||||
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)]
|
||||
/// <summary>
|
||||
/// 测试各种抛竿,未满足HutaoFisher判定,结果为运行中
|
||||
/// </summary>
|
||||
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)]
|
||||
/// <summary>
|
||||
/// 测试各种抛竿,无鱼饵适用鱼,结果为失败
|
||||
/// </summary>
|
||||
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
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -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<AutoFishingTask> stringLocalizer;
|
||||
private readonly InferenceSession session;
|
||||
private readonly Dictionary<string, float[]> 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<AutoFishingTask>();
|
||||
this.session = iconModel.modelLoader.Value.session;
|
||||
this.prototypes = iconModel.modelLoader.Value.prototypes;
|
||||
}
|
||||
|
||||
private IOcrService OcrService => paddle.Get();
|
||||
|
||||