mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-04-01 10:39:50 +08:00
pick drops
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using BetterGenshinImpact.View.Drawable;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Recognition.ONNX;
|
||||
|
||||
@@ -45,6 +46,16 @@ public class BgiYoloV8Predictor(string modelRelativePath) : IDisposable
|
||||
}
|
||||
}
|
||||
Debug.WriteLine("YOLOv8识别结果:" + JsonSerializer.Serialize(dict));
|
||||
|
||||
var list = new List<RectDrawable>();
|
||||
foreach (var box in result.Boxes)
|
||||
{
|
||||
var rect = new Rect(box.Bounds.X, box.Bounds.Y, box.Bounds.Width, box.Bounds.Height);
|
||||
list.Add(region.ToRectDrawable(rect, modelRelativePath));
|
||||
}
|
||||
|
||||
VisionContext.Instance().DrawContent.PutOrRemoveRectList(modelRelativePath, list);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Recognition.ONNX;
|
||||
|
||||
public class BgiYoloV8PredictorFactory
|
||||
{
|
||||
static Dictionary<string, BgiYoloV8Predictor> _predictors = new();
|
||||
|
||||
public static BgiYoloV8Predictor GetPredictor(string modelRelativePath)
|
||||
{
|
||||
if (!_predictors.ContainsKey(modelRelativePath))
|
||||
{
|
||||
_predictors[modelRelativePath] = new BgiYoloV8Predictor(modelRelativePath);
|
||||
}
|
||||
|
||||
return _predictors[modelRelativePath];
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.GameTask.AutoFight.Assets;
|
||||
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
||||
using BetterGenshinImpact.Core.Recognition.OpenCv;
|
||||
using BetterGenshinImpact.GameTask.Common.Job;
|
||||
using OpenCvSharp;
|
||||
using Vanara;
|
||||
|
||||
@@ -40,7 +41,7 @@ public class AutoFightTask : ISoloTask
|
||||
|
||||
if (_taskParam.FightFinishDetectEnabled)
|
||||
{
|
||||
_predictor = new BgiYoloV8Predictor(@"Assets\Model\World\bgi_world.onnx");
|
||||
_predictor = BgiYoloV8PredictorFactory.GetPredictor(@"Assets\Model\World\bgi_world.onnx");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +125,10 @@ public class AutoFightTask : ISoloTask
|
||||
|
||||
if (_taskParam is { FightFinishDetectEnabled: true, PickDropsAfterFightEnabled: true })
|
||||
{
|
||||
//
|
||||
|
||||
// 执行自动拾取掉落物的功能
|
||||
await new ScanPickTask().Start(ct);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.GameTask.AutoFight.Model;
|
||||
using BetterGenshinImpact.GameTask.AutoFight.Script;
|
||||
using BetterGenshinImpact.GameTask.AutoPathing.Model;
|
||||
using BetterGenshinImpact.GameTask.Common.Job;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
||||
|
||||
@@ -22,6 +23,8 @@ public class MiningHandler : IActionHandler
|
||||
坎蒂丝 e(hold)
|
||||
""");
|
||||
|
||||
private readonly ScanPickTask _scanPickTask = new();
|
||||
|
||||
public async Task RunAsync(CancellationToken ct, WaypointForTrack? waypointForTrack = null)
|
||||
{
|
||||
var combatScenes = await RunnerContext.Instance.GetCombatScenes(ct);
|
||||
@@ -30,14 +33,14 @@ public class MiningHandler : IActionHandler
|
||||
Logger.LogError("队伍识别未初始化成功!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 挖矿
|
||||
Mining(combatScenes);
|
||||
|
||||
|
||||
await Delay(1000, ct);
|
||||
|
||||
|
||||
// 拾取
|
||||
|
||||
await _scanPickTask.Start(ct);
|
||||
}
|
||||
|
||||
private void Mining(CombatScenes combatScenes)
|
||||
|
||||
110
BetterGenshinImpact/GameTask/Common/Job/ScanPickTask.cs
Normal file
110
BetterGenshinImpact/GameTask/Common/Job/ScanPickTask.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.Core.Recognition.ONNX;
|
||||
using BetterGenshinImpact.Core.Simulator;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using BetterGenshinImpact.View.Drawable;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenCvSharp;
|
||||
using Vanara.PInvoke;
|
||||
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
||||
|
||||
namespace BetterGenshinImpact.GameTask.Common.Job;
|
||||
|
||||
/// <summary>
|
||||
/// 扫描拾取任务
|
||||
/// 请在安全地区使用
|
||||
/// </summary>
|
||||
public class ScanPickTask
|
||||
{
|
||||
private readonly BgiYoloV8Predictor _predictor = BgiYoloV8PredictorFactory.GetPredictor(@"Assets\Model\World\bgi_world.onnx");
|
||||
private readonly double _dpi = TaskContext.Instance().DpiScale;
|
||||
private readonly RECT _realCaptureRect = TaskContext.Instance().SystemInfo.CaptureAreaRect;
|
||||
|
||||
|
||||
public async Task Start(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
await DoOnce(ct);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogDebug(e, "拾取周边物品异常");
|
||||
Logger.LogError("拾取周边物品异常: {Msg}", e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
VisionContext.Instance().DrawContent.ClearAll();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DoOnce(CancellationToken ct)
|
||||
{
|
||||
await ResetCamera(ct);
|
||||
|
||||
for (int n = 0; n < 5; n++) // 最多跑5次
|
||||
{
|
||||
var hasDrops = false;
|
||||
|
||||
// 旋转视角
|
||||
for (var i = 0; i < 20; i++)
|
||||
{
|
||||
var ra = CaptureToRectArea();
|
||||
var resultDic = _predictor.Detect(ra);
|
||||
// 过滤出可拾取物品
|
||||
var pickItems = resultDic.Where(x => x.Key is "drops" or "ore")
|
||||
.SelectMany(x => x.Value).ToList();
|
||||
|
||||
|
||||
if (pickItems.Count > 0)
|
||||
{
|
||||
hasDrops = true;
|
||||
// 把鼠标位置和物品位置重合
|
||||
MoveCursorTo(pickItems.First(), ra);
|
||||
await Delay(100, ct);
|
||||
// 物体越小,距离越远
|
||||
await WalkForward(ct);
|
||||
break;
|
||||
}
|
||||
|
||||
Simulation.SendInput.Mouse.MoveMouseBy((int)(300 * _dpi), 0);
|
||||
await Delay(100, ct);
|
||||
}
|
||||
|
||||
if (!hasDrops)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static async Task WalkForward(CancellationToken ct)
|
||||
{
|
||||
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
||||
await Delay(1000, ct);
|
||||
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W);
|
||||
}
|
||||
|
||||
private void MoveCursorTo(Rect item, ImageRegion ra)
|
||||
{
|
||||
var centerX = (item.Left + item.Right) / 2;
|
||||
var centerY = (item.Top + item.Bottom) / 2;
|
||||
var dx = centerX - ra.Width / 2;
|
||||
var dy = centerY - ra.Height / 2;
|
||||
var r = _realCaptureRect.Width * 1.0 / ra.Width; // 缩放比例
|
||||
Simulation.SendInput.Mouse.MoveMouseBy((int)(dx * r * _dpi), (int)(dy * r * _dpi));
|
||||
}
|
||||
|
||||
// 回正 并下移视角
|
||||
private async Task ResetCamera(CancellationToken ct)
|
||||
{
|
||||
// Simulation.SendInput.Keyboard.Mouse.MiddleButtonClick();
|
||||
// await Delay(500, ct);
|
||||
Simulation.SendInput.Keyboard.Mouse.MoveMouseBy(0, (int)(500 * _dpi));
|
||||
await Delay(100, ct);
|
||||
}
|
||||
}
|
||||
@@ -569,7 +569,10 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
// Task.Run(async () => { await new ClaimBattlePassRewardsTask().Start(new CancellationToken()); });
|
||||
|
||||
// 领取邮件奖励
|
||||
Task.Run(async () => { await new ClaimMailRewardsTask().Start(new CancellationToken()); });
|
||||
// Task.Run(async () => { await new ClaimMailRewardsTask().Start(new CancellationToken()); });
|
||||
|
||||
// 拾取物品
|
||||
Task.Run(async () => { await new ScanPickTask().Start(new CancellationToken()); });
|
||||
}
|
||||
));
|
||||
debugDirectory.Children.Add(new HotKeySettingModel(
|
||||
|
||||
Reference in New Issue
Block a user