Files
better-genshin-impact/Test/BetterGenshinImpact.UnitTest/GameTaskTests/AutoFishingTests/BehavioursTests.ThrowRod.cs
Takaranoao 5b3bac478d 升级多个依赖&增加额外的推理加速功能&迁移OCR (#1459)
* 更新多个NuGet包至最新版本

* 重构模型加载以适应yolosharp

* feat: 改变接口。TensorRT缓存的初步支持,修改配置项。

* 更新依赖并调整变量顺序,修复加载问题

* 更新AvalonEdit和Microsoft.ML.OnnxRuntime包至最新版本,以修复问题

* fix: downgrade Microsoft.ML.OnnxRuntime.DirectML to version 1.21.0

* typo

* fix: change log level from warning to error for ONNX provider loading failure

* 增加 paddle ocr 的 onnx 模型

* feat: add PaddleOCR models for Chinese, English, and Latin recognition

* 使用cv的DNN生成Tensor,加速Yap文字识别

* feat: 尝试搓一个onnx的ocr

* clean up code

* chore: update OpenCvSharp4 package versions to 4.10.0.20241108

* 修复因格式化代码而丢的引用

* chore: update Microsoft.ML.OnnxRuntime.DirectML package to version 1.21.1 and improve logging for ONNX provider initialization

* chore: 等yolosharp更新再升级onnx

* chore: add Microsoft.ML.OnnxRuntime.Managed package and clean up logging in Det class

* fix: refactor output tensor handling in Det class for improved clarity

* 补充注释,修复DML的OCR问题

* 默认OCR推理使用CPU,整理配置

* fix error NETSDK1152: 找到了多个具有相同相对路径的发布输出文件

* fix(logging): enhance debug log for ONNX initialization with provider details

* 修复TensorRT模型缓存的加载问题

* fix(onnx): improve cached model retrieval and add file existence check

* fix(ocr): replace SrcGreyMat with SrcMat for region of interest processing

* fix(onnx): add file existence check for cached model and adjust session options for DirectML provider

* 增加硬件加速配置UI界面

* 移除旧的OCR模型

* 错别字

---------

Co-authored-by: 辉鸭蛋 <huiyadanli@gmail.com>
2025-05-11 01:08:37 +08:00

253 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BehaviourTree;
using BetterGenshinImpact.GameTask.AutoFishing;
using BetterGenshinImpact.GameTask.Model.Area.Converter;
using BetterGenshinImpact.GameTask.Model.Area;
using Microsoft.Extensions.Time.Testing;
using OpenCvSharp;
using BehaviourTree.Composites;
using BehaviourTree.FluentBuilder;
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")]
/// <summary>
/// 测试各种抛竿,结果为成功
/// </summary>
public void ThrowRodTest_VariousFish_ShouldSuccess(string screenshot1080p, string selectedBaitName)
{
//
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}");
var imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(new FakeMouseSimulator()), converter: new ScaleConverter(1d), drawContent: new FakeDrawContent());
var blackboard = new Blackboard(Predictor, sleep: i => { })
{
selectedBaitName = selectedBaitName
};
FakeTimeProvider fakeTimeProvider = new FakeTimeProvider();
//
ThrowRod sut = new ThrowRod("-", blackboard, new FakeLogger(), false, new FakeInputSimulator(), fakeTimeProvider, drawContent: new FakeDrawContent());
BehaviourStatus actual = sut.Tick(imageRegion);
//
Assert.False(blackboard.throwRodNoBaitFish);
Assert.Equal(BehaviourStatus.Succeeded, actual);
}
[Theory]
[InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "redrot bait")]
[InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "fake fly bait")]
/// <summary>
/// 测试各种抛竿未满足HutaoFisher判定结果为运行中
/// </summary>
public void ThrowRodTest_VariousFish_ShouldFail(string screenshot1080p, string selectedBaitName)
{
//
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}");
var imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(new FakeMouseSimulator()), converter: new ScaleConverter(1d), drawContent: new FakeDrawContent());
var blackboard = new Blackboard(Predictor, sleep: i => { })
{
selectedBaitName = selectedBaitName
};
FakeTimeProvider fakeTimeProvider = new FakeTimeProvider();
//
ThrowRod sut = new ThrowRod("-", blackboard, new FakeLogger(), false, new FakeInputSimulator(), fakeTimeProvider, drawContent: new FakeDrawContent());
BehaviourStatus actual = sut.Tick(imageRegion);
//
Assert.False(blackboard.throwRodNoBaitFish);
Assert.Equal(BehaviourStatus.Running, actual);
}
[Theory]
[InlineData(@"20250225101304534_ThrowRod_Succeeded.png", "flashing maintenance mek bait")]
/// <summary>
/// 测试各种抛竿,无鱼饵适用鱼,结果为失败
/// </summary>
public void ThrowRodTest_NoBaitFish_ShouldFail(string screenshot1080p, string selectedBaitName)
{
//
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}");
var imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(new FakeMouseSimulator()), converter: new ScaleConverter(1d), drawContent: new FakeDrawContent());
var blackboard = new Blackboard(Predictor, sleep: i => { })
{
selectedBaitName = selectedBaitName
};
FakeTimeProvider fakeTimeProvider = new FakeTimeProvider();
//
ThrowRod sut = new ThrowRod("-", blackboard, new FakeLogger(), false, new FakeInputSimulator(), fakeTimeProvider, drawContent: new FakeDrawContent());
BehaviourStatus actual = sut.Tick(imageRegion);
//
Assert.False(blackboard.throwRodNoBaitFish);
Assert.Equal(BehaviourStatus.Running, actual);
//
// Do nothing
//
for (int i = 0; i < 10; i++)
{
sut.Tick(imageRegion);
}
//
Assert.True(blackboard.throwRodNoBaitFish);
}
/// <summary>
/// 抛竿时,给定三条炮鲀鱼,并且确定算法能将下杆点从鱼的左侧移动到最左侧的炮鲀鱼上,此时希望“当前鱼”能始终锁定在最左侧的鱼上
/// 由于偶尔观测到“摇摆”行为的出现,故设计此测试
/// </summary>
[Fact]
public void ThrowRodTest_Target_ShouldBeTheLeftOne()
{
//
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\202503082114541115.png");
var imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(new FakeMouseSimulator()), converter: new ScaleConverter(1d), drawContent: new FakeDrawContent());
var blackboard = new Blackboard(Predictor, sleep: i => { })
{
selectedBaitName = "fake fly bait"
};
//
ThrowRod sut = new ThrowRod("-", blackboard, new FakeLogger(), false, new FakeInputSimulator(), new FakeTimeProvider(), drawContent: new FakeDrawContent());
sut.Tick(imageRegion);
var actual = sut.currentFish;
//
Assert.True(blackboard.fishpond.TargetRect != null && blackboard.fishpond.TargetRect.Value != default);
Assert.Equal(3, blackboard.fishpond.Fishes.Count(f => f.FishType.Name == "pufferfish"));
Assert.Equal(blackboard.fishpond.Fishes.OrderBy(f => f.Rect.X).First(), actual);
//
mat = new Mat(@$"..\..\..\Assets\AutoFishing\202503082114560489.png");
imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(new FakeMouseSimulator()), converter: new ScaleConverter(1d), drawContent: new FakeDrawContent());
//
sut.Tick(imageRegion);
actual = sut.currentFish;
//
Assert.Equal(3, blackboard.fishpond.Fishes.Count(f => f.FishType.Name == "pufferfish"));
Assert.Equal(blackboard.fishpond.Fishes.OrderBy(f => f.Rect.X).First(), actual);
}
[Theory]
[InlineData(@"202502252347412417.png")]
[InlineData(@"202503012143011486@900p.png")]
/// <summary>
/// 测试各种抛竿,超时未找到落点,结果为失败
/// </summary>
public void ThrowRodTest_NoTarget_ShouldFail(string screenshot1080p)
{
//
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}");
var imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(new FakeMouseSimulator()), converter: new ScaleConverter(1d), drawContent: new FakeDrawContent());
var blackboard = new Blackboard(Predictor, sleep: i => { });
FakeTimeProvider fakeTimeProvider = new FakeTimeProvider();
//
ThrowRod sut = new ThrowRod("-", blackboard, new FakeLogger(), false, new FakeInputSimulator(), fakeTimeProvider, drawContent: new FakeDrawContent());
BehaviourStatus actual = sut.Tick(imageRegion);
//
Assert.False(blackboard.throwRodNoTarget);
Assert.Equal(BehaviourStatus.Running, actual);
//
fakeTimeProvider.Advance(TimeSpan.FromSeconds(5.1));
//
actual = sut.Tick(imageRegion);
//
Assert.True(blackboard.throwRodNoTarget);
Assert.Equal(BehaviourStatus.Failed, actual);
}
[Theory]
[InlineData(@"202502252347412417.png")]
/// <summary>
/// 测试抛竿循环3次超时未找到落点结果为失败并退出
/// </summary>
public void ThrowRodTest_NoTarget_3Times_ShouldFailAndAbort(string screenshot1080p)
{
//
Mat mat = new Mat(@$"..\..\..\Assets\AutoFishing\{screenshot1080p}");
FakeInputSimulator input = new FakeInputSimulator();
FakeDrawContent drawContent = new FakeDrawContent();
var imageRegion = new GameCaptureRegion(mat, 0, 0, new DesktopRegion(input.Mouse), converter: new ScaleConverter(1d), drawContent: drawContent);
var blackboard = new Blackboard(Predictor, sleep: i => { });
FakeTimeProvider timeProvider = new FakeTimeProvider();
FakeLogger logger = new FakeLogger();
//
var sut = FluentBuilder.Create<ImageRegion>()
.MySimpleParallel("抛竿直到成功或出错", policy: SimpleParallelPolicy.OnlyOneMustSucceed)
.UntilSuccess("重复抛竿")
.Sequence("-")
.PushLeaf(() => new MoveViewpointDown("调整视角至俯视", blackboard, logger, false, input))
.PushLeaf(() => new ThrowRod("抛竿", blackboard, logger, false, input, timeProvider, drawContent))
.End()
.End()
.Do("抛竿检查", _ => (blackboard.abort || blackboard.throwRodNoTarget || blackboard.throwRodNoBaitFish) ? BehaviourStatus.Failed : BehaviourStatus.Running)
.End()
.Build();
sut.Tick(imageRegion);
sut.Tick(imageRegion);
timeProvider.Advance(TimeSpan.FromSeconds(5.1));
BehaviourStatus actual = sut.Tick(imageRegion);
//
Assert.True(blackboard.throwRodNoTarget);
Assert.Equal(1, blackboard.throwRodNoTargetTimes);
Assert.Equal(BehaviourStatus.Failed, actual);
//
//
sut.Tick(imageRegion);
sut.Tick(imageRegion);
timeProvider.Advance(TimeSpan.FromSeconds(5.1));
actual = sut.Tick(imageRegion);
//
Assert.True(blackboard.throwRodNoTarget);
Assert.Equal(2, blackboard.throwRodNoTargetTimes);
Assert.Equal(BehaviourStatus.Failed, actual);
//
//
sut.Tick(imageRegion);
sut.Tick(imageRegion);
timeProvider.Advance(TimeSpan.FromSeconds(5.1));
actual = sut.Tick(imageRegion);
//
Assert.True(blackboard.throwRodNoTarget);
Assert.Equal(3, blackboard.throwRodNoTargetTimes);
Assert.Equal(BehaviourStatus.Failed, actual);
Assert.True(blackboard.abort);
}
}
}