diff --git a/BetterGenshinImpact.Test/MainWindow.xaml.cs b/BetterGenshinImpact.Test/MainWindow.xaml.cs
index a1ef7986..73121911 100644
--- a/BetterGenshinImpact.Test/MainWindow.xaml.cs
+++ b/BetterGenshinImpact.Test/MainWindow.xaml.cs
@@ -37,7 +37,7 @@ public partial class MainWindow : Window
private void DoMatchTemplateTest(object sender, System.Windows.RoutedEventArgs e)
{
- MatchTemplateTest.TestMenu();
+ MatchTemplateTest.TestTrack();
}
private void DoMatchTest(object sender, System.Windows.RoutedEventArgs e)
diff --git a/BetterGenshinImpact.Test/Simple/AllMap/MatchTemplateTest.cs b/BetterGenshinImpact.Test/Simple/AllMap/MatchTemplateTest.cs
index ae04cabc..0ca04dec 100644
--- a/BetterGenshinImpact.Test/Simple/AllMap/MatchTemplateTest.cs
+++ b/BetterGenshinImpact.Test/Simple/AllMap/MatchTemplateTest.cs
@@ -25,6 +25,16 @@ public class MatchTemplateTest
Cv2.ImWrite(@"E:\HuiTask\更好的原神\地图匹配\x1.png", src2);
}
+ public static void TestTrack()
+ {
+ var tar = new Mat(@"E:\HuiTask\更好的原神\自动剧情\任务剧情与地图追踪\blue_task_point_28x.png", ImreadModes.Grayscale);
+ var src = new Mat(@"E:\HuiTask\更好的原神\自动剧情\任务剧情与地图追踪\202404050232291883.png", ImreadModes.Grayscale);
+ var src2 = src.Clone();
+ var p = MatchTemplateHelper.MatchTemplate(src, tar, TemplateMatchModes.CCoeffNormed, null, 0.1);
+ Cv2.Rectangle(src2, new Rect(p.X, p.Y, tar.Width, tar.Height), new Scalar(0, 0, 255), 1);
+ Cv2.ImWrite(@"E:\HuiTask\更好的原神\自动剧情\任务剧情与地图追踪\rec_b1.png", src2);
+ }
+
public static void TestMenu()
{
var tar = new Mat(@"D:\HuiPrograming\Projects\CSharp\MiHoYo\BetterGenshinImpact\BetterGenshinImpact\GameTask\Common\Element\Assets\1920x1080\paimon_menu.png", ImreadModes.Color);
diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj
index 1cf7e93e..e5fab82d 100644
--- a/BetterGenshinImpact/BetterGenshinImpact.csproj
+++ b/BetterGenshinImpact/BetterGenshinImpact.csproj
@@ -364,6 +364,9 @@
Always
+
+ Always
+
Always
@@ -448,6 +451,9 @@
Always
+
+ Always
+
Always
diff --git a/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs b/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs
index e2a8fc79..2ec61924 100644
--- a/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs
+++ b/BetterGenshinImpact/GameTask/AutoSkip/AutoSkipTrigger.cs
@@ -232,11 +232,6 @@ public class AutoSkipTrigger : ITaskTrigger
return false;
}
- private bool AutoTrack(CaptureContent content)
- {
- return false;
- }
-
private void HangoutOptionChoose(CaptureContent content)
{
var selectedRects = MatchTemplateHelper.MatchOnePicForOnePic(content.CaptureRectArea.SrcGreyMat, _autoSkipAssets.HangoutSelectedMat);
diff --git a/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs b/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs
new file mode 100644
index 00000000..0dba29a1
--- /dev/null
+++ b/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs
@@ -0,0 +1,296 @@
+using BetterGenshinImpact.Core.Recognition;
+using BetterGenshinImpact.Core.Recognition.OCR;
+using BetterGenshinImpact.Core.Recognition.OpenCv;
+using BetterGenshinImpact.Core.Simulator;
+using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
+using BetterGenshinImpact.GameTask.AutoSkip.Model;
+using BetterGenshinImpact.GameTask.Common.Element.Assets;
+using BetterGenshinImpact.GameTask.Model;
+using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
+using BetterGenshinImpact.Helpers;
+using BetterGenshinImpact.Service.Notification;
+using BetterGenshinImpact.View.Drawable;
+using Microsoft.Extensions.Logging;
+using OpenCvSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using BetterGenshinImpact.GameTask.Common;
+using BetterGenshinImpact.GameTask.Common.BgiVision;
+using BetterGenshinImpact.ViewModel.Pages;
+using Vanara.PInvoke;
+using static BetterGenshinImpact.GameTask.Common.TaskControl;
+using WinRT;
+
+namespace BetterGenshinImpact.GameTask.AutoSkip;
+
+public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
+{
+ // ///
+ // /// 准备好前进了
+ // ///
+ // private bool _readyMoveForward = false;
+
+ ///
+ /// 任务距离
+ ///
+ private Rect _missionDistanceRect = Rect.Empty;
+
+ public async void Start()
+ {
+ var hasLock = false;
+ try
+ {
+ hasLock = await TaskSemaphore.WaitAsync(0);
+ if (!hasLock)
+ {
+ Logger.LogError("启动自动追踪功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
+ return;
+ }
+
+ SystemControl.ActivateWindow();
+
+ TrackMission();
+ }
+ catch (NormalEndException e)
+ {
+ Logger.LogInformation("自动追踪中断:" + e.Message);
+ // NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Cancelled().Build());
+ }
+ catch (Exception e)
+ {
+ Logger.LogError(e.Message);
+ Logger.LogDebug(e.StackTrace);
+ // NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Failure().Build());
+ }
+ finally
+ {
+ VisionContext.Instance().DrawContent.ClearAll();
+ TaskSettingsPageViewModel.SetSwitchAutoTrackButtonText(false);
+ Logger.LogInformation("→ {Text}", "自动追踪结束");
+
+ if (hasLock)
+ {
+ TaskSemaphore.Release();
+ }
+ }
+ }
+
+ private void TrackMission()
+ {
+ // 确认在主界面才会执行跟随任务
+ var ra = GetRectAreaFromDispatcher();
+ var paimonMenuRa = ra.Find(ElementAssets.Instance.PaimonMenuRo);
+ if (!paimonMenuRa.IsExist())
+ {
+ Sleep(5000, param.Cts);
+ return;
+ }
+
+ // 任务文字有动效,等待2s重新截图
+ Simulation.SendInputEx.Mouse.MoveMouseBy(0, 7000);
+ Sleep(2000, param.Cts);
+
+ // OCR 任务文字 在小地图下方
+ var textRaList = OcrMissionTextRaList(paimonMenuRa);
+ if (textRaList.Count == 0)
+ {
+ Logger.LogInformation("未找到任务文字");
+ Sleep(5000, param.Cts);
+ return;
+ }
+
+ // 从任务文字中提取距离
+ var distance = GetDistanceFromMissionText(textRaList);
+ Logger.LogInformation("任务追踪:{Text}", "距离" + distance + "m");
+ if (distance >= 150)
+ {
+ // 距离大于150米,先传送到最近的传送点
+ // J 打开任务 切换追踪打开地图 中心点就是任务点
+ Simulation.SendInputEx.Keyboard.KeyPress(User32.VK.VK_J);
+ Sleep(800, param.Cts);
+ // TODO 识别是否在任务界面
+ // 切换追踪
+ var btn = ra.DerivePoint(CaptureRect.Width - 250, CaptureRect.Height - 60);
+ btn.ClickCenter();
+ Sleep(200, param.Cts);
+ btn.ClickCenter();
+ Sleep(1500, param.Cts);
+
+ // 寻找所有传送点
+ ra = GetRectAreaFromDispatcher();
+ var tpPointList = MatchTemplateHelper.MatchMultiPicForOnePic(ra.SrcGreyMat, QuickTeleportAssets.Instance.MapChooseIconGreyMatList);
+ if (tpPointList.Count > 0)
+ {
+ // 选中离中心点最近的传送点
+ var centerX = ra.Width / 2;
+ var centerY = ra.Height / 2;
+ var minDistance = double.MaxValue;
+ var nearestRect = Rect.Empty;
+ foreach (var tpPoint in tpPointList)
+ {
+ var distanceTp = Math.Sqrt(Math.Pow(Math.Abs(tpPoint.X - centerX), 2) + Math.Pow(Math.Abs(tpPoint.Y - centerY), 2));
+ if (distanceTp < minDistance)
+ {
+ minDistance = distanceTp;
+ nearestRect = tpPoint;
+ }
+ }
+
+ ra.Derive(nearestRect).ClickCenter();
+ // 等待自动传送完成
+ Sleep(2000, param.Cts);
+
+ if (Bv.IsInBigMapUi(GetRectAreaFromDispatcher()))
+ {
+ Logger.LogWarning("仍旧在大地图界面,传送失败");
+ }
+ else
+ {
+ Sleep(500, param.Cts);
+ NewRetry.Do(() =>
+ {
+ if (!Bv.IsInMainUi(GetRectAreaFromDispatcher()))
+ {
+ Logger.LogInformation("未进入到主界面,继续等待");
+ throw new RetryException("未进入到主界面");
+ }
+ }, TimeSpan.FromSeconds(1), 100);
+ StartTrackPoint();
+ }
+ }
+ else
+ {
+ Logger.LogWarning("未找到传送点");
+ }
+ }
+ else
+ {
+ StartTrackPoint();
+ }
+ }
+
+ private void StartTrackPoint()
+ {
+ // V键直接追踪
+ Simulation.SendInputEx.Keyboard.KeyPress(User32.VK.VK_V);
+ Sleep(3000, param.Cts);
+
+ var ra = GetRectAreaFromDispatcher();
+ var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
+ if (blueTrackPointRa.IsExist())
+ {
+ MakeBlueTrackPointDirectlyAbove();
+ }
+ else
+ {
+ Logger.LogWarning("首次未找到追踪点");
+ }
+ }
+
+ ///
+ /// 找到追踪点并调整方向
+ ///
+ private void MakeBlueTrackPointDirectlyAbove()
+ {
+ // return new Task(() =>
+ // {
+ int prevMoveX = 0;
+ bool wDown = false;
+ while (!param.Cts.Token.IsCancellationRequested)
+ {
+ var ra = GetRectAreaFromDispatcher();
+ var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
+ if (blueTrackPointRa.IsExist())
+ {
+ // 调整整体高度
+ var centerY = blueTrackPointRa.Y + blueTrackPointRa.Height / 2;
+ if (centerY > CaptureRect.Height / 2)
+ {
+ Simulation.SendInputEx.Mouse.MoveMouseBy(-100, 0);
+ if (wDown)
+ {
+ Simulation.SendInputEx.Keyboard.KeyUp(User32.VK.VK_W);
+ wDown = false;
+ }
+
+ continue;
+ }
+
+ // 调整方向
+ var centerX = blueTrackPointRa.X + blueTrackPointRa.Width / 2;
+ var moveX = centerX - CaptureRect.Width / 2;
+ if (moveX != 0)
+ {
+ Simulation.SendInputEx.Mouse.MoveMouseBy(moveX, 0);
+ }
+
+ if (moveX == 0 || prevMoveX * moveX < 0)
+ {
+ if (!wDown)
+ {
+ Simulation.SendInputEx.Keyboard.KeyDown(User32.VK.VK_W);
+ wDown = true;
+ }
+ }
+
+ if (Math.Abs(moveX) < 50 && Math.Abs(centerY - CaptureRect.Height / 2) < 200)
+ {
+ if (wDown)
+ {
+ Simulation.SendInputEx.Keyboard.KeyUp(User32.VK.VK_W);
+ wDown = false;
+ }
+ // 识别距离
+ var text = OcrFactory.Paddle.OcrWithoutDetector(ra.SrcGreyMat[_missionDistanceRect]);
+ if (StringUtils.TryExtractPositiveInt(text) is > -1 and <= 3)
+ {
+ Logger.LogInformation("任务追踪:到达目标,识别结果[{Text}]", text);
+ break;
+ }
+ Logger.LogInformation("任务追踪:到达目标");
+ break;
+ }
+
+ prevMoveX = moveX;
+ }
+ else
+ {
+ // 随机移动
+ Logger.LogInformation("未找到追踪点");
+ }
+
+ Simulation.SendInputEx.Mouse.MoveMouseBy(0, 500); // 保证俯视角
+ Sleep(100);
+ }
+ // });
+ }
+
+ private int GetDistanceFromMissionText(List textRaList)
+ {
+ // 打印所有任务文字
+ var text = textRaList.Aggregate(string.Empty, (current, textRa) => current + textRa.Text.Trim() + "|");
+ Logger.LogInformation("任务追踪:{Text}", text);
+
+ foreach (var textRa in textRaList)
+ {
+ if (textRa.Text.Length < 8 && (textRa.Text.Contains("m") || textRa.Text.Contains("M")))
+ {
+ _missionDistanceRect = textRa.ConvertRelativePositionToCaptureArea();
+ return StringUtils.TryExtractPositiveInt(textRa.Text);
+ }
+ }
+
+ return -1;
+ }
+
+ private List OcrMissionTextRaList(RectArea paimonMenuRa)
+ {
+ return GetRectAreaFromDispatcher().FindMulti(new RecognitionObject
+ {
+ RecognitionType = RecognitionTypes.Ocr,
+ RegionOfInterest = new Rect(paimonMenuRa.X, paimonMenuRa.Y - 15 + 210,
+ (int)(300 * AssetScale), (int)(100 * AssetScale))
+ });
+ }
+}
diff --git a/BetterGenshinImpact/GameTask/AutoSkip/Model/AutoTrackParam.cs b/BetterGenshinImpact/GameTask/AutoSkip/Model/AutoTrackParam.cs
new file mode 100644
index 00000000..36bdeca4
--- /dev/null
+++ b/BetterGenshinImpact/GameTask/AutoSkip/Model/AutoTrackParam.cs
@@ -0,0 +1,11 @@
+using System.Threading;
+using BetterGenshinImpact.GameTask.Model;
+
+namespace BetterGenshinImpact.GameTask.AutoSkip.Model;
+
+public class AutoTrackParam : BaseTaskParam
+{
+ public AutoTrackParam(CancellationTokenSource cts) : base(cts)
+ {
+ }
+}
diff --git a/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/blue_task_point_28x.png b/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/blue_track_point_28x.png
similarity index 100%
rename from BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/blue_task_point_28x.png
rename to BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/blue_track_point_28x.png
diff --git a/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/yellow_task_point_28x.png b/BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/yellow_track_point_28x.png
similarity index 100%
rename from BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/yellow_task_point_28x.png
rename to BetterGenshinImpact/GameTask/Common/Element/Assets/1920x1080/yellow_track_point_28x.png
diff --git a/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs b/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs
index 1ff3fabf..ce2868ff 100644
--- a/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs
+++ b/BetterGenshinImpact/GameTask/Common/Element/Assets/ElementAssets.cs
@@ -10,11 +10,10 @@ public class ElementAssets : BaseAssets
public RecognitionObject BtnWhiteCancel;
public RecognitionObject BtnBlackConfirm;
public RecognitionObject PaimonMenuRo;
+ public RecognitionObject BlueTrackPoint;
private ElementAssets()
{
- var info = TaskContext.Instance().SystemInfo;
-
// 按钮
BtnWhiteConfirm = new RecognitionObject
{
@@ -44,8 +43,18 @@ public class ElementAssets : BaseAssets
Name = "PaimonMenu",
RecognitionType = RecognitionTypes.TemplateMatch,
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "paimon_menu.png"),
- RegionOfInterest = new Rect(0, 0, info.CaptureAreaRect.Width / 4, info.CaptureAreaRect.Height / 4),
+ RegionOfInterest = new Rect(0, 0, CaptureRect.Width / 4, CaptureRect.Height / 4),
DrawOnWindow = false
}.InitTemplate();
+
+ // 任务追踪点位
+ BlueTrackPoint = new RecognitionObject
+ {
+ Name = "BlueTrackPoint",
+ RecognitionType = RecognitionTypes.TemplateMatch,
+ TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "blue_track_point_28x.png"),
+ RegionOfInterest = new Rect((int)(300 * AssetScale), 0, CaptureRect.Width - (int)(600 * AssetScale), CaptureRect.Height),
+ DrawOnWindow = true
+ }.InitTemplate();
}
}
diff --git a/BetterGenshinImpact/GameTask/Common/TaskControl.cs b/BetterGenshinImpact/GameTask/Common/TaskControl.cs
index f212efca..d2990a08 100644
--- a/BetterGenshinImpact/GameTask/Common/TaskControl.cs
+++ b/BetterGenshinImpact/GameTask/Common/TaskControl.cs
@@ -1,4 +1,5 @@
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
+using BetterGenshinImpact.GameTask.Model;
using Fischless.GameCapture;
using Microsoft.Extensions.Logging;
using System;
@@ -132,8 +133,18 @@ public class TaskControl
return CaptureToContent(TaskTriggerDispatcher.GlobalGameCapture);
}
+ public static RectArea CaptureToRectArea()
+ {
+ return CaptureToContent().CaptureRectArea;
+ }
+
public static CaptureContent GetContentFromDispatcher()
{
return TaskTriggerDispatcher.Instance().GetLastCaptureContent();
}
+
+ public static RectArea GetRectAreaFromDispatcher()
+ {
+ return GetContentFromDispatcher().CaptureRectArea;
+ }
}
diff --git a/BetterGenshinImpact/GameTask/Model/BaseIndependentTask.cs b/BetterGenshinImpact/GameTask/Model/BaseIndependentTask.cs
new file mode 100644
index 00000000..65939d70
--- /dev/null
+++ b/BetterGenshinImpact/GameTask/Model/BaseIndependentTask.cs
@@ -0,0 +1,11 @@
+using BetterGenshinImpact.Helpers;
+using Vanara.PInvoke;
+
+namespace BetterGenshinImpact.GameTask.Model;
+
+public class BaseIndependentTask
+{
+ protected SystemInfo Info => TaskContext.Instance().SystemInfo;
+ protected RECT CaptureRect => TaskContext.Instance().SystemInfo.CaptureAreaRect;
+ protected double AssetScale => TaskContext.Instance().SystemInfo.AssetScale;
+}
diff --git a/BetterGenshinImpact/GameTask/Model/IndependentTaskEnum.cs b/BetterGenshinImpact/GameTask/Model/IndependentTaskEnum.cs
index 5e809801..33b1ec79 100644
--- a/BetterGenshinImpact/GameTask/Model/IndependentTaskEnum.cs
+++ b/BetterGenshinImpact/GameTask/Model/IndependentTaskEnum.cs
@@ -2,9 +2,9 @@
public enum IndependentTaskEnum
{
-
AutoGeniusInvokation,
AutoWood,
AutoFight,
AutoDomain,
-}
\ No newline at end of file
+ AutoTrack,
+}
diff --git a/BetterGenshinImpact/GameTask/Model/RectArea.cs b/BetterGenshinImpact/GameTask/Model/RectArea.cs
index 4f02a679..48def9c2 100644
--- a/BetterGenshinImpact/GameTask/Model/RectArea.cs
+++ b/BetterGenshinImpact/GameTask/Model/RectArea.cs
@@ -11,8 +11,10 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
+using Microsoft.Extensions.Logging;
using Sdcb.PaddleOCR;
using Point = OpenCvSharp.Point;
+using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask.Model;
@@ -252,6 +254,11 @@ public class RectArea : IDisposable
if (ro.RegionOfInterest != Rect.Empty)
{
// TODO roi 是可以加缓存的
+ if (!(0 <= ro.RegionOfInterest.X && 0 <= ro.RegionOfInterest.Width && ro.RegionOfInterest.X + ro.RegionOfInterest.Width <= roi.Cols
+ && 0 <= ro.RegionOfInterest.Y && 0 <= ro.RegionOfInterest.Height && ro.RegionOfInterest.Y + ro.RegionOfInterest.Height <= roi.Rows))
+ {
+ Logger.LogError("输入图像{W1}x{H1},模板ROI区域{H2}x{W2},边界溢出!", roi.Width, roi.Height, ro.RegionOfInterest.Width, ro.RegionOfInterest.Height);
+ }
roi = new Mat(roi, ro.RegionOfInterest);
}
@@ -453,7 +460,12 @@ public class RectArea : IDisposable
if (result.Regions.Length > 0)
{
- var resRaList = result.Regions.Select(r => this.Derive(r.Rect.BoundingRect() + new Point(ro.RegionOfInterest.X, ro.RegionOfInterest.Y))).ToList();
+ var resRaList = result.Regions.Select(r =>
+ {
+ var newRa = this.Derive(r.Rect.BoundingRect() + new Point(ro.RegionOfInterest.X, ro.RegionOfInterest.Y));
+ newRa.Text = r.Text;
+ return newRa;
+ }).ToList();
if (ro.DrawOnWindow && !string.IsNullOrEmpty(ro.Name))
{
VisionContext.Instance().DrawContent.PutOrRemoveRectList(ro.Name, result.ToRectDrawableListOffset(ro.RegionOfInterest.X, ro.RegionOfInterest.Y));
@@ -531,6 +543,18 @@ public class RectArea : IDisposable
return new RectArea(rect, this);
}
+ ///
+ /// 派生2x2区域(无图片)
+ /// 方便用于点击
+ ///
+ ///
+ ///
+ ///
+ public RectArea DerivePoint(int x, int y)
+ {
+ return new RectArea(new Rect(x, y, 2, 2), this);
+ }
+
///
/// OCR识别
///
diff --git a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs
index 4a10e159..5071edda 100644
--- a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs
+++ b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs
@@ -21,6 +21,8 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using BetterGenshinImpact.GameTask.AutoSkip;
+using BetterGenshinImpact.GameTask.AutoSkip.Model;
using Vanara.PInvoke;
namespace BetterGenshinImpact.GameTask
@@ -216,6 +218,10 @@ namespace BetterGenshinImpact.GameTask
{
Task.Run(() => { new AutoDomainTask((AutoDomainParam)param).Start(); });
}
+ else if (taskType == IndependentTaskEnum.AutoTrack)
+ {
+ Task.Run(() => { new AutoTrackTask((AutoTrackParam)param).Start(); });
+ }
}
public void Dispose() => Stop();
diff --git a/BetterGenshinImpact/Helpers/ClickOffset.cs b/BetterGenshinImpact/Helpers/ClickOffset.cs
index 8ddcdafa..70b3d59e 100644
--- a/BetterGenshinImpact/Helpers/ClickOffset.cs
+++ b/BetterGenshinImpact/Helpers/ClickOffset.cs
@@ -1,10 +1,6 @@
using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.Helpers.Extensions;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace BetterGenshinImpact.Helpers;
@@ -14,7 +10,6 @@ public class ClickOffset
public int OffsetY { get; set; }
public double AssetScale { get; set; }
-
public ClickOffset()
{
if (!TaskContext.Instance().IsInitialized)
@@ -54,4 +49,4 @@ public class ClickOffset
{
ClickExtension.Move(OffsetX + (int)(x * AssetScale), OffsetY + (int)(y * AssetScale));
}
-}
\ No newline at end of file
+}
diff --git a/BetterGenshinImpact/Helpers/StringUtils.cs b/BetterGenshinImpact/Helpers/StringUtils.cs
index 303dd92d..f2664d82 100644
--- a/BetterGenshinImpact/Helpers/StringUtils.cs
+++ b/BetterGenshinImpact/Helpers/StringUtils.cs
@@ -1,4 +1,6 @@
-namespace BetterGenshinImpact.Helpers;
+using System.Text.RegularExpressions;
+
+namespace BetterGenshinImpact.Helpers;
public class StringUtils
{
@@ -101,4 +103,22 @@ public class StringUtils
return 0;
}
}
+
+ public static int TryExtractPositiveInt(string text)
+ {
+ if (string.IsNullOrEmpty(text))
+ {
+ return -1;
+ }
+
+ try
+ {
+ text = Regex.Replace(text, @"[^0-9]+", "");
+ return int.Parse(text);
+ }
+ catch
+ {
+ return -1;
+ }
+ }
}
diff --git a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml
index d32ba0b3..8103d8cd 100644
--- a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml
+++ b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml
@@ -1,8 +1,8 @@
- 全自动打牌 -
-
+ 全自动打牌 -
点击查看使用教程
@@ -201,9 +199,7 @@
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
TextWrapping="Wrap">
- 需要装备「王树瑞佑」 -
-
+ 需要装备「王树瑞佑」 -
点击查看使用教程
@@ -293,9 +289,7 @@
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
TextWrapping="Wrap">
- 自动执行选择的战斗策略 -
-
+ 自动执行选择的战斗策略 -
点击查看使用教程
@@ -394,9 +388,7 @@
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
TextWrapping="Wrap">
- 基于钟离的自动循环刷本 -
-
+ 基于钟离的自动循环刷本 -
点击查看使用教程
@@ -515,12 +507,11 @@
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="如果电脑性能较差,寻找古树时间过久,可以尝试使用这个功能"
TextWrapping="Wrap" />
-
+
@@ -541,12 +532,11 @@
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="如果电脑性能较差,开启秘境或者领取奖励的F点击不到,可以尝试此功能"
TextWrapping="Wrap" />
-
+
@@ -603,6 +593,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 自动走路跟踪剧情任务,不支持每日任务 -
+ 点击查看使用教程
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+