Merge pull request #726 from babalae/feat-cts

refactor: CancellationTokenSource -> CancellationToken
This commit is contained in:
辉鸭蛋 2024-10-19 13:10:38 +08:00 committed by GitHub
commit 790d42cee0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 278 additions and 256 deletions

View File

@ -9,7 +9,7 @@ public class AutoPathingScript(string rootPath)
public async Task Run(string json)
{
var task = PathingTask.BuildFromJson(json);
await new PathExecutor(CancellationContext.Instance.Cts).Pathing(task);
await new PathExecutor(CancellationContext.Instance.Cts.Token).Pathing(task);
}
public async Task RunFile(string path)

View File

@ -77,7 +77,7 @@ public class Dispatcher
{
return;
}
await new AutoDomainTask(new AutoDomainParam(0, path)).Start(CancellationContext.Instance.Cts);
await new AutoDomainTask(new AutoDomainParam(0, path)).Start(CancellationContext.Instance.Cts.Token);
break;
case "AutoMusicGame":

View File

@ -37,7 +37,7 @@ public class Genshin
/// <returns></returns>
public async Task Tp(double x, double y)
{
await new TpTask(CancellationContext.Instance.Cts).Tp(x, y);
await new TpTask(CancellationContext.Instance.Cts.Token).Tp(x, y);
}
/// <summary>

View File

@ -137,7 +137,7 @@ public partial class ScriptGroupProject : ObservableObject
// 加载并执行
var task = PathingTask.BuildFromFilePath(Path.Combine(MapPathingViewModel.PathJsonPath, FolderName, Name));
TaskTriggerDispatcher.Instance().AddTrigger("AutoPick", null);
await new PathExecutor(CancellationContext.Instance.Cts).Pathing(task);
await new PathExecutor(CancellationContext.Instance.Cts.Token).Pathing(task);
}
else
{

View File

@ -1,7 +1,6 @@
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Recognition.OCR;
using BetterGenshinImpact.Core.Recognition.ONNX;
using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.Core.Simulator;
using BetterGenshinImpact.GameTask.AutoFight;
using BetterGenshinImpact.GameTask.AutoFight.Assets;
@ -26,7 +25,7 @@ using System.Threading;
using System.Threading.Tasks;
using Vanara.PInvoke;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
using static Vanara.PInvoke.Gdi32;
using static Vanara.PInvoke.Kernel32;
using static Vanara.PInvoke.User32;
namespace BetterGenshinImpact.GameTask.AutoDomain;
@ -43,7 +42,7 @@ public class AutoDomainTask : ISoloTask
private readonly CombatScriptBag _combatScriptBag;
private CancellationTokenSource? _cts;
private CancellationToken _ct;
public AutoDomainTask(AutoDomainParam taskParam)
{
@ -60,9 +59,9 @@ public class AutoDomainTask : ISoloTask
_combatScriptBag = CombatScriptParser.ReadAndParse(_taskParam.CombatStrategyPath);
}
public async Task Start(CancellationTokenSource cts)
public async Task Start(CancellationToken ct)
{
_cts = cts;
_ct = ct;
AutoFightAssets.DestroyInstance();
Init();
@ -169,7 +168,7 @@ public class AutoDomainTask : ISoloTask
Simulation.SendInput.Keyboard.KeyPress(VK.VK_F);
Logger.LogInformation("自动秘境:{Text}", "进入秘境");
// 秘境开门动画 5s
Sleep(5000, _cts);
Sleep(5000, _ct);
}
int retryTimes = 0, clickCount = 0;
@ -183,11 +182,11 @@ public class AutoDomainTask : ISoloTask
clickCount++;
}
Sleep(1500, _cts);
Sleep(1500, _ct);
}
// 载入动画
Sleep(3000, _cts);
Sleep(3000, _ct);
}
private void CloseDomainTip()
@ -200,16 +199,16 @@ public class AutoDomainTask : ISoloTask
using var cactRectArea = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.ClickAnyCloseTipRa);
if (!cactRectArea.IsEmpty())
{
Sleep(1000, _cts);
Sleep(1000, _ct);
cactRectArea.Click();
break;
}
// todo 添加小地图角标位置检测 防止有人手点了
Sleep(1000, _cts);
Sleep(1000, _ct);
}
Sleep(1500, _cts);
Sleep(1500, _ct);
}
private List<CombatCommand> FindCombatScriptAndSwitchAvatar(CombatScenes combatScenes)
@ -226,7 +225,7 @@ public class AutoDomainTask : ISoloTask
/// </summary>
private async Task WalkToPressF()
{
if (_cts.Token.IsCancellationRequested)
if (_ct.IsCancellationRequested)
{
return;
}
@ -243,12 +242,12 @@ public class AutoDomainTask : ISoloTask
try
{
while (!_cts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested)
{
using var fRectArea = Common.TaskControl.CaptureToRectArea().Find(AutoPickAssets.Instance.FRo);
if (fRectArea.IsEmpty())
{
Sleep(100, _cts);
Sleep(100, _ct);
}
else
{
@ -273,8 +272,8 @@ public class AutoDomainTask : ISoloTask
private Task StartFight(CombatScenes combatScenes, List<CombatCommand> combatCommands)
{
CancellationTokenSource cts = new();
_cts.Token.Register(cts.Cancel);
combatScenes.BeforeTask(cts);
_ct.Register(cts.Cancel);
combatScenes.BeforeTask(cts.Token);
// 战斗操作
var combatTask = new Task(() =>
{
@ -307,7 +306,7 @@ public class AutoDomainTask : ISoloTask
// 对局结束检测
var domainEndTask = DomainEndDetectionTask(cts);
// 自动吃药
var autoEatRecoveryHpTask = AutoEatRecoveryHpTask(cts);
var autoEatRecoveryHpTask = AutoEatRecoveryHpTask(cts.Token);
combatTask.Start();
domainEndTask.Start();
autoEatRecoveryHpTask.Start();
@ -316,7 +315,7 @@ public class AutoDomainTask : ISoloTask
private void EndFightWait()
{
if (_cts.Token.IsCancellationRequested)
if (_ct.IsCancellationRequested)
{
return;
}
@ -325,7 +324,7 @@ public class AutoDomainTask : ISoloTask
if (s > 0)
{
Logger.LogInformation("战斗结束后等待 {Second} 秒", s);
Sleep((int)(s * 1000), _cts);
Sleep((int)(s * 1000), _ct);
}
}
@ -338,7 +337,7 @@ public class AutoDomainTask : ISoloTask
{
try
{
while (!_cts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested)
{
if (IsDomainEnd())
{
@ -346,7 +345,7 @@ public class AutoDomainTask : ISoloTask
break;
}
await Delay(1000, cts);
await Delay(1000, cts.Token);
}
}
catch
@ -378,7 +377,7 @@ public class AutoDomainTask : ISoloTask
return false;
}
private Task AutoEatRecoveryHpTask(CancellationTokenSource cts)
private Task AutoEatRecoveryHpTask(CancellationToken ct)
{
return new Task(async () =>
{
@ -394,7 +393,7 @@ public class AutoDomainTask : ISoloTask
try
{
while (!_cts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested)
{
if (IsLowHealth())
{
@ -404,13 +403,13 @@ public class AutoDomainTask : ISoloTask
// TODO 吃饱了会一直吃
}
await Delay(500, cts);
await Delay(500, ct);
}
}
catch
{
}
}, cts.Token);
}, ct);
}
private bool IsLowHealth()
@ -442,10 +441,10 @@ public class AutoDomainTask : ISoloTask
private Task FindPetrifiedTree()
{
CancellationTokenSource treeCts = new();
_cts.Token.Register(treeCts.Cancel);
_ct.Register(treeCts.Cancel);
// 中键回正视角
Simulation.SendInput.Mouse.MiddleButtonClick();
Sleep(900, _cts);
Sleep(900, _ct);
// 左右移动直到石化古树位于屏幕中心任务
var moveAvatarTask = MoveAvatarHorizontallyTask(treeCts);
@ -467,7 +466,7 @@ public class AutoDomainTask : ISoloTask
var noDetectCount = 0;
var prevKey = VK.VK_A;
var backwardsAndForwardsCount = 0;
while (!_cts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested)
{
var treeRect = DetectTree(CaptureToRectArea());
if (treeRect != Rect.Empty)
@ -550,7 +549,7 @@ public class AutoDomainTask : ISoloTask
else
{
_simulator.KeyPress(VK.VK_W, 60);
Sleep(500, _cts);
Sleep(500, _ct);
treeCts.Cancel();
break;
}
@ -595,12 +594,12 @@ public class AutoDomainTask : ISoloTask
{
// 左右移动5次说明已经在树中心了
_simulator.KeyPress(VK.VK_W, 60);
Sleep(500, _cts);
Sleep(500, _ct);
treeCts.Cancel();
break;
}
Sleep(60, _cts);
Sleep(60, _ct);
}
VisionContext.Instance().DrawContent.ClearAll();
@ -701,7 +700,7 @@ public class AutoDomainTask : ISoloTask
private bool GettingTreasure(bool recognizeResin, bool isLastTurn)
{
// 等待窗口弹出
Sleep(1500, _cts);
Sleep(1500, _ct);
// 优先使用浓缩树脂
var retryTimes = 0;
@ -720,22 +719,22 @@ public class AutoDomainTask : ISoloTask
useCondensedResinRa.Click();
// 点两下 #224 #218
// 解决水龙王按下左键后没松开,然后后续点击按下就没反应了
Sleep(400, _cts);
Sleep(400, _ct);
useCondensedResinRa.Click();
break;
}
Sleep(800, _cts);
Sleep(800, _ct);
}
Sleep(1000, _cts);
Sleep(1000, _ct);
var captureArea = TaskContext.Instance().SystemInfo.CaptureAreaRect;
for (var i = 0; i < 30; i++)
{
// 跳过领取动画
GameCaptureRegion.GameRegionClick((size, scale) => (size.Width - 140 * scale, 53 * scale));
Sleep(200, _cts);
Sleep(200, _ct);
GameCaptureRegion.GameRegionClick((size, scale) => (size.Width - 140 * scale, 53 * scale));
// 优先点击继续
@ -779,7 +778,7 @@ public class AutoDomainTask : ISoloTask
}
}
Sleep(300, _cts);
Sleep(300, _ct);
}
throw new NormalEndException("未检测到秘境结束,可能是背包物品已满。");

View File

@ -21,7 +21,7 @@ public class AutoFightTask : ISoloTask
private readonly CombatScriptBag _combatScriptBag;
private CancellationTokenSource? _cts;
private CancellationToken _ct;
private readonly BgiYoloV8Predictor _predictor;
@ -38,9 +38,9 @@ public class AutoFightTask : ISoloTask
}
}
public async Task Start(CancellationTokenSource cts)
public async Task Start(CancellationToken ct)
{
_cts = cts;
_ct = ct;
LogScreenResolution();
var combatScenes = new CombatScenes().InitializeTeam(CaptureToRectArea());
@ -53,9 +53,9 @@ public class AutoFightTask : ISoloTask
// 新的取消token
var cts2 = new CancellationTokenSource();
cts.Token.Register(cts2.Cancel);
ct.Register(cts2.Cancel);
combatScenes.BeforeTask(cts2);
combatScenes.BeforeTask(cts2.Token);
// 战斗操作
var fightTask = Task.Run(() =>
@ -97,7 +97,7 @@ public class AutoFightTask : ISoloTask
break;
}
Sleep(1000, cts2);
Sleep(1000, cts2.Token);
}
}
catch (Exception e)
@ -138,11 +138,11 @@ public class AutoFightTask : ISoloTask
{
// 旋转完毕后都没有检测到血条和怪物位置则按L键确认战斗结束
List<int> angles = [0, 90, 180, 270];
var rotateTask = new CameraRotateTask(_cts!);
var rotateTask = new CameraRotateTask(_ct);
foreach (var a in angles)
{
await rotateTask.WaitUntilRotatedTo(a, 5, 30);
await Delay(1000, _cts!); // 等待视角稳定
await Delay(1000, _ct!); // 等待视角稳定
if (HasFightFlag(CaptureToRectArea()))
{
return false;

View File

@ -72,7 +72,7 @@ public class Avatar
/// <summary>
/// 任务取消令牌
/// </summary>
public CancellationTokenSource? Cts { get; set; }
public CancellationToken Ct { get; set; }
/// <summary>
/// 战斗场景
@ -106,7 +106,7 @@ public class Avatar
if (!confirmRectArea.IsEmpty())
{
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);
Sleep(600, Cts);
Sleep(600, Ct);
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_M);
throw new Exception("存在角色被击败,按 M 键打开地图,并停止自动秘境。");
}
@ -120,7 +120,7 @@ public class Avatar
{
for (var i = 0; i < 30; i++)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}
@ -137,7 +137,7 @@ public class Avatar
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_1 + (byte)Index - 1);
// Debug.WriteLine($"切换到{Index}号位");
// Cv2.ImWrite($"log/切换.png", content.CaptureRectArea.SrcMat);
Sleep(250, Cts);
Sleep(250, Ct);
}
}
@ -248,14 +248,14 @@ public class Avatar
{
while (ms >= 0)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}
AutoFightContext.Instance.Simulator.LeftButtonClick();
ms -= 200;
Sleep(200, Cts);
Sleep(200, Ct);
}
}
@ -266,7 +266,7 @@ public class Avatar
{
for (var i = 0; i < 1; i++)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}
@ -276,7 +276,7 @@ public class Avatar
if (Name == "纳西妲")
{
AutoFightContext.Instance.Simulator.KeyDown(User32.VK.VK_E);
Sleep(300, Cts);
Sleep(300, Ct);
for (int j = 0; j < 10; j++)
{
Simulation.SendInput.Mouse.MoveMouseBy(1000, 0);
@ -296,7 +296,7 @@ public class Avatar
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_E);
}
Sleep(200, Cts);
Sleep(200, Ct);
var region = CaptureToRectArea();
ThrowWhenDefeated(region);
@ -331,13 +331,13 @@ public class Avatar
// var isBurstReleased = false;
for (var i = 0; i < 10; i++)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_Q);
Sleep(200, Cts);
Sleep(200, Ct);
var region = CaptureToRectArea();
ThrowWhenDefeated(region);
@ -345,7 +345,7 @@ public class Avatar
if (notActiveCount == 0)
{
// isBurstReleased = true;
Sleep(1500, Cts);
Sleep(1500, Ct);
return;
}
// else
@ -381,7 +381,7 @@ public class Avatar
/// </summary>
public void Dash(int ms = 0)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}
@ -398,7 +398,7 @@ public class Avatar
public void Walk(string key, int ms)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}
@ -473,7 +473,7 @@ public class Avatar
AutoFightContext.Instance.Simulator.LeftButtonDown();
while (ms >= 0)
{
if (Cts is { IsCancellationRequested: true })
if (Ct is { IsCancellationRequested: true })
{
return;
}

View File

@ -188,11 +188,11 @@ public class CombatScenes : IDisposable
return avatars;
}
public void BeforeTask(CancellationTokenSource cts)
public void BeforeTask(CancellationToken ct)
{
for (var i = 0; i < AvatarCount; i++)
{
Avatars[i].Cts = cts;
Avatars[i].Ct = ct;
}
}

View File

@ -53,7 +53,7 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
if (_cts == null || _cts.Token.IsCancellationRequested)
{
_cts = new CancellationTokenSource();
_fightTask = FightTask(_cts);
_fightTask = FightTask(_cts.Token);
if (!_fightTask.IsCompleted)
{
_fightTask.Start();
@ -65,7 +65,7 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
if (_cts == null || _cts.Token.IsCancellationRequested)
{
_cts = new CancellationTokenSource();
_fightTask = FightTask(_cts);
_fightTask = FightTask(_cts.Token);
if (!_fightTask.IsCompleted)
{
_fightTask.Start();
@ -126,14 +126,14 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
/// <summary>
/// 循环执行战斗宏
/// </summary>
private Task FightTask(CancellationTokenSource cts)
private Task FightTask(CancellationToken ct)
{
// 切换截图模式
var dispatcherCaptureMode = TaskTriggerDispatcher.Instance().GetCacheCaptureMode();
if (dispatcherCaptureMode != DispatcherCaptureModeEnum.CacheCaptureWithTrigger)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
Sleep(TaskContext.Instance().Config.TriggerInterval * 2, cts); // 等待缓存图像
Sleep(TaskContext.Instance().Config.TriggerInterval * 2, ct); // 等待缓存图像
}
var imageRegion = CaptureToRectArea();
@ -162,7 +162,7 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
return new Task(() =>
{
Logger.LogInformation("→ {Name}执行宏", activeAvatar.Name);
while (!cts.Token.IsCancellationRequested && IsEnabled())
while (!ct.IsCancellationRequested && IsEnabled())
{
if (IsHoldOnMode() && !_isKeyDown)
{

View File

@ -5,11 +5,11 @@ namespace BetterGenshinImpact.GameTask.AutoGeniusInvokation;
public class AutoGeniusInvokationTask(GeniusInvokationTaskParam taskParam) : ISoloTask
{
public Task Start(CancellationTokenSource cts)
public Task Start(CancellationToken ct)
{
// 读取策略信息
var duel = ScriptParser.Parse(taskParam.StrategyContent);
duel.Run(cts);
duel.Run(ct);
return Task.CompletedTask;
}
}

View File

@ -61,15 +61,15 @@ public class GeniusInvokationControl
public static bool OutputImageWhenError = true;
private CancellationTokenSource? _cts;
private CancellationToken _ct;
private readonly AutoGeniusInvokationAssets _assets = AutoGeniusInvokationAssets.Instance;
// private IGameCapture? _gameCapture;
public void Init(CancellationTokenSource cts)
public void Init(CancellationToken ct)
{
_cts = cts;
_ct = ct;
// _gameCapture = taskParam.Dispatcher.GameCapture;
}
@ -103,7 +103,7 @@ public class GeniusInvokationControl
{
NewRetry.Do(() =>
{
if (_cts is { IsCancellationRequested: true })
if (_ct is { IsCancellationRequested: true })
{
return;
}
@ -115,7 +115,7 @@ public class GeniusInvokationControl
}
}, TimeSpan.FromSeconds(1), 100);
if (_cts is { IsCancellationRequested: true })
if (_ct is { IsCancellationRequested: true })
{
throw new TaskCanceledException("任务取消");
}

View File

@ -1,11 +1,9 @@
using BetterGenshinImpact.Core.Recognition.OpenCv;
using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Assets;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.Service.Notification;
using BetterGenshinImpact.View.Drawable;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System;
@ -50,25 +48,22 @@ public class Duel
/// </summary>
public int CurrentDiceCount { get; set; } = 0;
public CancellationTokenSource Cts { get; set; } = default!;
private int _keqingECount = 0;
public async Task RunAsync(CancellationTokenSource cts)
public async Task RunAsync(CancellationToken ct)
{
await Task.Run(() => { Run(cts); });
await Task.Run(() => { Run(ct); }, ct);
}
public void Run(CancellationTokenSource cts)
public void Run(CancellationToken ct)
{
Cts = cts;
try
{
AutoGeniusInvokationAssets.DestroyInstance();
LogScreenResolution();
NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Started().Build()); // TODO 需要移动
GeniusInvokationControl.GetInstance().Init(Cts);
GeniusInvokationControl.GetInstance().Init(ct);
// 对局准备 选择初始手牌
GeniusInvokationControl.GetInstance().CommonDuelPrepare();

View File

@ -1,5 +1,4 @@
using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.Core.Simulator;
using BetterGenshinImpact.Core.Simulator;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System;
@ -28,7 +27,7 @@ public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
private readonly IntPtr _hWnd = TaskContext.Instance().GameHandle;
public Task Start(CancellationTokenSource cts)
public Task Start(CancellationToken ct)
{
Init();
@ -43,16 +42,16 @@ public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
{
var (x, y) = gameCaptureRegion.ConvertPositionToGameCaptureRegion((int)(keyValuePair.Value * assetScale), (int)(_keyY * assetScale));
// 添加任务
taskList.Add(taskFactory.StartNew(() => DoWhitePressWin32(cts, keyValuePair.Key, new Point(x, y))));
taskList.Add(taskFactory.StartNew(() => DoWhitePressWin32(ct, keyValuePair.Key, new Point(x, y))));
}
Task.WaitAll([.. taskList]);
return Task.CompletedTask;
}
private void DoWhitePressWin32(CancellationTokenSource cts, User32.VK key, Point point)
private void DoWhitePressWin32(CancellationToken ct, User32.VK key, Point point)
{
while (!cts.Token.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
Thread.Sleep(10);
// Stopwatch sw = new();
@ -64,7 +63,7 @@ public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
if (c.B < 220)
{
KeyDown(key);
while (!cts.Token.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
Thread.Sleep(10);
hdc = User32.GetDC(_hWnd);

View File

@ -9,7 +9,7 @@ using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask.AutoPathing;
public class CameraRotateTask(CancellationTokenSource cts)
public class CameraRotateTask(CancellationToken ct)
{
private readonly double _dpi = TaskContext.Instance().DpiScale;
@ -59,7 +59,7 @@ public class CameraRotateTask(CancellationTokenSource cts)
public async Task WaitUntilRotatedTo(int targetOrientation, int maxDiff, int maxTryTimes = 50)
{
int count = 0;
while (!cts.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
var screen = CaptureToRectArea();
if (Math.Abs(RotateToApproach(targetOrientation, screen)) < maxDiff)
@ -73,7 +73,7 @@ public class CameraRotateTask(CancellationTokenSource cts)
break;
}
await Delay(50, cts);
await Delay(50, ct);
count++;
}
}

View File

@ -11,12 +11,12 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
internal class AutoFightHandler : IActionHandler
{
public async Task RunAsync(CancellationTokenSource cts)
public async Task RunAsync(CancellationToken ct)
{
await StartFight(cts);
await StartFight(ct);
}
private async Task StartFight(CancellationTokenSource cts)
private async Task StartFight(CancellationToken ct)
{
TaskControl.Logger.LogInformation("执行 {Text}", "自动战斗");
// 爷们要战斗
@ -26,7 +26,7 @@ internal class AutoFightHandler : IActionHandler
PickDropsAfterFightEnabled = true
};
var fightSoloTask = new AutoFightTask(taskParams);
await fightSoloTask.Start(cts);
await fightSoloTask.Start(ct);
}
private string GetFightStrategy()

View File

@ -13,7 +13,7 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
/// </summary>
public class ElementalSkillHandler : IActionHandler
{
public Task RunAsync(CancellationTokenSource cts)
public Task RunAsync(CancellationToken ct)
{
TaskControl.Logger.LogInformation("执行 {Text}", "释放元素战技");
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_E);

View File

@ -5,5 +5,5 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
public interface IActionHandler
{
Task RunAsync(CancellationTokenSource cts);
Task RunAsync(CancellationToken ct);
}

View File

@ -15,13 +15,13 @@ public class NahidaCollectHandler : IActionHandler
{
private DateTime lastETime = DateTime.MinValue;
public async Task RunAsync(CancellationTokenSource cts)
public async Task RunAsync(CancellationToken ct)
{
Logger.LogInformation("执行 {Nhd} 长按E转圈拾取", "纳西妲");
var cd = DateTime.Now - lastETime;
if (cd < TimeSpan.FromSeconds(10))
{
await Delay((int)((6 - cd.TotalSeconds + 0.5) * 1000), cts);
await Delay((int)((6 - cd.TotalSeconds + 0.5) * 1000), ct);
}
var dpi = TaskContext.Instance().DpiScale;
@ -30,21 +30,21 @@ public class NahidaCollectHandler : IActionHandler
int i = 60;
// 视角拉到最下面
Simulation.SendInput.Mouse.MoveMouseBy(0, 10000);
await Delay(200, cts);
await Delay(200, ct);
// 按住E技能 无死角扫码
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_E);
await Delay(200, cts);
await Delay(200, ct);
// 先地面来一圈
for (int j = 0; j < 15; j++)
{
Simulation.SendInput.Mouse.MoveMouseBy(x, 500);
await Delay(30, cts);
await Delay(30, ct);
}
// 然后抬斜向转圈
while (!cts.IsCancellationRequested && i > 0)
while (!ct.IsCancellationRequested && i > 0)
{
i--;
if (i == 40)
@ -53,17 +53,17 @@ public class NahidaCollectHandler : IActionHandler
}
Simulation.SendInput.Mouse.MoveMouseBy(x, y);
await Delay(30, cts);
await Delay(30, ct);
}
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_E);
lastETime = DateTime.Now;
await Delay(1000, cts);
await Delay(1000, ct);
// 恢复视角
Simulation.SendInput.Mouse.MiddleButtonClick();
await Delay(1000, cts);
await Delay(1000, ct);
}
}

View File

@ -11,7 +11,7 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
/// </summary>
public class NormalAttackHandler : IActionHandler
{
public Task RunAsync(CancellationTokenSource cts)
public Task RunAsync(CancellationToken ct)
{
TaskControl.Logger.LogInformation("执行 {Text}", "普通攻击");

View File

@ -14,11 +14,11 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
/// </summary>
public class PickAroundHandler : IActionHandler
{
public async Task RunAsync(CancellationTokenSource cts)
public async Task RunAsync(CancellationToken ct)
{
var screen = CaptureToRectArea();
var angle = 0;
CameraRotateTask rotateTask = new(cts);
CameraRotateTask rotateTask = new(ct);
TaskControl.Logger.LogInformation("执行 {Text}", "小范围内自动拾取");
await rotateTask.WaitUntilRotatedTo(angle, 5);
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
@ -29,7 +29,7 @@ public class PickAroundHandler : IActionHandler
rotateTask.RotateToApproach(angle, screen);
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_F);
await Delay(100, cts);
await Delay(100, ct);
if (DateTime.UtcNow - startTime > TimeSpan.FromSeconds(5))
break;
}

View File

@ -20,10 +20,10 @@ using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask.AutoPathing;
public class PathExecutor(CancellationTokenSource cts)
public class PathExecutor(CancellationToken ct)
{
private readonly CameraRotateTask _rotateTask = new(cts);
private readonly TrapEscaper _trapEscaper = new(cts);
private readonly CameraRotateTask _rotateTask = new(ct);
private readonly TrapEscaper _trapEscaper = new(ct);
public async Task Pathing(PathingTask task)
{
@ -37,7 +37,7 @@ public class PathExecutor(CancellationTokenSource cts)
var waypoints = ConvertWaypointsForTrack(task.Positions);
await Delay(100, cts);
await Delay(100, ct);
Navigation.WarmUp(); // 提前加载地图特征点
try
@ -85,7 +85,7 @@ public class PathExecutor(CancellationTokenSource cts)
private async Task HandleTeleportWaypoint(WaypointForTrack waypoint)
{
var forceTp = waypoint.Action == ActionEnum.ForceTp.Code;
var (tpX, tpY) = await new TpTask(cts).Tp(waypoint.GameX, waypoint.GameY, forceTp);
var (tpX, tpY) = await new TpTask(ct).Tp(waypoint.GameX, waypoint.GameY, forceTp);
var (tprX, tprY) = MapCoordinate.GameToMain2048(tpX, tpY);
EntireMap.Instance.SetPrevPosition((float)tprX, (float)tprY); // 通过上一个位置直接进行局部特征匹配
}
@ -105,7 +105,7 @@ public class PathExecutor(CancellationTokenSource cts)
// 按下w一直走
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
while (!cts.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
var now = DateTime.UtcNow;
if ((now - startTime).TotalSeconds > 240)
@ -168,7 +168,7 @@ public class PathExecutor(CancellationTokenSource cts)
{
Debug.WriteLine("未进入飞行状态,按下空格");
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
await Delay(200, cts);
await Delay(200, ct);
}
continue;
@ -177,7 +177,7 @@ public class PathExecutor(CancellationTokenSource cts)
if (waypoint.MoveMode == MoveModeEnum.Jump.Code)
{
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
await Delay(200, cts);
await Delay(200, ct);
continue;
}
@ -210,7 +210,7 @@ public class PathExecutor(CancellationTokenSource cts)
}
}
await Delay(100, cts);
await Delay(100, ct);
}
// 抬起w键
@ -228,12 +228,12 @@ public class PathExecutor(CancellationTokenSource cts)
//下落攻击接近目的地
Logger.LogInformation("动作:下落攻击");
Simulation.SendInput.Mouse.LeftButtonClick();
await Delay(1000, cts);
await Delay(1000, ct);
}
await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2);
var stepsTaken = 0;
while (!cts.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
stepsTaken++;
if (stepsTaken > 20)
@ -254,13 +254,13 @@ public class PathExecutor(CancellationTokenSource cts)
await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2);
// 小碎步接近
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W).Sleep(60).KeyUp(User32.VK.VK_W);
await Delay(50, cts);
await Delay(50, ct);
}
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W);
// 到达目的地后停顿一秒
await Delay(1000, cts);
await Delay(1000, ct);
}
private async Task AfterMoveToTarget(Waypoint waypoint)
@ -270,8 +270,8 @@ public class PathExecutor(CancellationTokenSource cts)
|| waypoint.Action == ActionEnum.Fight.Code)
{
var handler = ActionFactory.GetHandler(waypoint.Action);
await handler.RunAsync(cts);
await Delay(800, cts);
await handler.RunAsync(ct);
await Delay(800, ct);
}
}
}

View File

@ -10,9 +10,9 @@ using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask.AutoPathing;
public class TrapEscaper(CancellationTokenSource cts)
public class TrapEscaper(CancellationToken ct)
{
private readonly CameraRotateTask _rotateTask = new(cts);
private readonly CameraRotateTask _rotateTask = new(ct);
private static readonly Random _random = new Random();
private int _lastActionIndex = 0;
public static DateTime LastActionTime = DateTime.UtcNow;
@ -39,7 +39,7 @@ public class TrapEscaper(CancellationTokenSource cts)
// 按下w一直走
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
while (!cts.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
var now = DateTime.UtcNow;
if ((now - LastActionTime).TotalSeconds > 5)
@ -106,7 +106,7 @@ public class TrapEscaper(CancellationTokenSource cts)
continue;
}
await Delay(100, cts);
await Delay(100, ct);
}
// 抬起w键
@ -119,9 +119,9 @@ public class TrapEscaper(CancellationTokenSource cts)
// 脱离攀爬状态
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W);
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_X);
await Delay(75, cts);
await Delay(75, ct);
Simulation.SendInput.Mouse.LeftButtonClick();
await Delay(500, cts);
await Delay(500, ct);
TimeSpan timeSinceLastAction = DateTime.UtcNow - LastActionTime;

View File

@ -13,7 +13,6 @@ using BetterGenshinImpact.GameTask.Model.Area;
using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.View.Drawable;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System;
@ -38,7 +37,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
/// </summary>
private Rect _missionDistanceRect = Rect.Empty;
private CancellationTokenSource? _cts;
private CancellationToken _ct;
public async void Start()
{
@ -56,7 +55,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
Logger.LogInformation("→ {Text}", "自动追踪,启动!");
_cts = CancellationContext.Instance.Cts;
_ct = CancellationContext.Instance.Cts.Token;
TrackMission();
}
@ -90,20 +89,20 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
var paimonMenuRa = ra.Find(ElementAssets.Instance.PaimonMenuRo);
if (!paimonMenuRa.IsExist())
{
Sleep(5000, _cts);
Sleep(5000, _ct);
return;
}
// 任务文字有动效等待2s重新截图
Simulation.SendInput.Mouse.MoveMouseBy(0, 7000);
Sleep(2000, _cts);
Sleep(2000, _ct);
// OCR 任务文字 在小地图下方
var textRaList = OcrMissionTextRaList(paimonMenuRa);
if (textRaList.Count == 0)
{
Logger.LogInformation("未找到任务文字");
Sleep(5000, _cts);
Sleep(5000, _ct);
return;
}
@ -115,14 +114,14 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
// 距离大于150米先传送到最近的传送点
// J 打开任务 切换追踪打开地图 中心点就是任务点
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_J);
Sleep(800, _cts);
Sleep(800, _ct);
// TODO 识别是否在任务界面
// 切换追踪
var btn = ra.Derive(CaptureRect.Width - 250, CaptureRect.Height - 60);
btn.Click();
Sleep(200, _cts);
Sleep(200, _ct);
btn.Click();
Sleep(1500, _cts);
Sleep(1500, _ct);
// 寻找所有传送点
ra = CaptureToRectArea();
@ -146,7 +145,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
ra.Derive(nearestRect).Click();
// 等待自动传送完成
Sleep(2000, _cts);
Sleep(2000, _ct);
if (Bv.IsInBigMapUi(CaptureToRectArea()))
{
@ -154,7 +153,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
}
else
{
Sleep(500, _cts);
Sleep(500, _ct);
NewRetry.Do(() =>
{
if (!Bv.IsInMainUi(CaptureToRectArea()))
@ -181,7 +180,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
{
// V键直接追踪
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_V);
Sleep(3000, _cts);
Sleep(3000, _ct);
var ra = CaptureToRectArea();
var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
@ -204,7 +203,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
// {
int prevMoveX = 0;
bool wDown = false;
while (!_cts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested)
{
var ra = CaptureToRectArea();
var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);

View File

@ -13,7 +13,6 @@ using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.Helpers.Extensions;
using BetterGenshinImpact.Service;
using BetterGenshinImpact.View.Drawable;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System;
@ -45,7 +44,7 @@ public class AutoTrackPathTask
// 视角偏移移动单位
private const int CharMovingUnit = 500;
private CancellationTokenSource? _cts;
private CancellationToken _ct;
public AutoTrackPathTask(AutoTrackPathParam taskParam)
{
@ -67,7 +66,7 @@ public class AutoTrackPathTask
return;
}
_cts = CancellationContext.Instance.Cts;
_ct = CancellationContext.Instance.Cts.Token;
Init();
@ -102,19 +101,14 @@ public class AutoTrackPathTask
SystemControl.ActivateWindow();
Logger.LogInformation("→ {Text}", "自动路线,启动!");
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
Sleep(TaskContext.Instance().Config.TriggerInterval * 5, _cts); // 等待缓存图像
}
public void Stop()
{
_cts.Cancel();
Sleep(TaskContext.Instance().Config.TriggerInterval * 5, _ct); // 等待缓存图像
}
public async Task DoTask()
{
// 1. 传送到最近的传送点
var first = _way.WayPointList[0]; // 解析路线,第一个点为起点
await new TpTask(_cts).Tp(first.Pt.X, first.Pt.Y);
await new TpTask(_ct).Tp(first.Pt.X, first.Pt.Y);
// 2. 等待传送完成
Sleep(1000);
@ -136,23 +130,23 @@ public class AutoTrackPathTask
// 4. 针对点位进行直线追踪
var trackCts = new CancellationTokenSource();
_cts.Token.Register(trackCts.Cancel);
_ct.Register(trackCts.Cancel);
var trackTask = Track(_way.WayPointList, angleOffset, trackCts);
trackTask.Start();
var refreshStatusTask = RefreshStatus(trackCts);
var refreshStatusTask = RefreshStatus(trackCts.Token);
refreshStatusTask.Start();
var jumpTask = Jump(trackCts);
var jumpTask = Jump(trackCts.Token);
jumpTask.Start();
await Task.WhenAll(trackTask, refreshStatusTask, jumpTask);
}
private MotionStatus _motionStatus = MotionStatus.Normal;
public Task Jump(CancellationTokenSource trackCts)
public Task Jump(CancellationToken trackCt)
{
return new Task(() =>
{
while (!_cts.Token.IsCancellationRequested && !trackCts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested && !trackCt.IsCancellationRequested)
{
if (_motionStatus == MotionStatus.Normal)
{
@ -178,11 +172,11 @@ public class AutoTrackPathTask
private double _targetAngle = 0;
public Task RefreshStatus(CancellationTokenSource trackCts)
public Task RefreshStatus(CancellationToken trackCt)
{
return new Task(() =>
{
while (!_cts.Token.IsCancellationRequested && !trackCts.Token.IsCancellationRequested)
while (!_ct.IsCancellationRequested && !trackCt.IsCancellationRequested)
{
using var ra = CaptureToRectArea();
_motionStatus = Bv.GetMotionStatus(ra);
@ -210,7 +204,7 @@ public class AutoTrackPathTask
return new Task(() =>
{
var currIndex = 0;
while (!_cts.IsCancellationRequested)
while (!_ct.IsCancellationRequested)
{
var ra = CaptureToRectArea();
var miniMapMat = GetMiniMapMat(ra) ?? throw new InvalidOperationException("当前不在主界面");

View File

@ -37,7 +37,7 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
_recordTaskCts = new CancellationTokenSource();
_recordTask = RecordTask(_recordTaskCts);
_recordTask = RecordTask(_recordTaskCts.Token);
_recordTask.Start();
}
else
@ -58,17 +58,17 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
}
}
public Task RecordTask(CancellationTokenSource cts)
public Task RecordTask(CancellationToken ct)
{
return new Task(() =>
{
GiPath way = new();
while (!cts.Token.IsCancellationRequested)
while (!ct.IsCancellationRequested)
{
try
{
Sleep(10, cts);
Sleep(10, ct);
var ra = CaptureToRectArea();
// 小地图匹配
@ -76,7 +76,7 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
var p = MatchTemplateHelper.MatchTemplate(ra.SrcGreyMat, tar, TemplateMatchModes.CCoeffNormed, null, 0.9);
if (p.X == 0 || p.Y == 0)
{
Sleep(50, cts);
Sleep(50, ct);
continue;
}
@ -88,7 +88,7 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
}
else
{
Sleep(50, cts);
Sleep(50, ct);
}
}
catch (Exception e)
@ -100,6 +100,6 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
File.WriteAllText(Global.Absolute($@"log\way\{DateTime.Now:yyyy-MM-dd HHmmssffff}.json"), JsonSerializer.Serialize(way, ConfigService.JsonOptions));
#endif
Logger.LogInformation("路线录制结束");
}, cts.Token);
}, ct);
}
}

View File

@ -25,7 +25,7 @@ namespace BetterGenshinImpact.GameTask.AutoTrackPath;
/// <summary>
/// 传送任务
/// </summary>
public class TpTask(CancellationTokenSource cts)
public class TpTask(CancellationToken ct)
{
private readonly QuickTeleportAssets _assets = QuickTeleportAssets.Instance;
@ -55,7 +55,7 @@ public class TpTask(CancellationTokenSource cts)
if (!Bv.IsInBigMapUi(ra1))
{
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_M);
await Delay(1000, cts);
await Delay(1000, ct);
}
// 计算传送点位置离哪个地图切换后的中心点最近,切换到该地图
@ -79,13 +79,13 @@ public class TpTask(CancellationTokenSource cts)
ra.ClickTo((int)clickX, (int)clickY);
// 触发一次快速传送功能
await Delay(500, cts);
await Delay(500, ct);
await ClickTpPoint(CaptureToRectArea());
// 等待传送完成
for (var i = 0; i < 20; i++)
{
await Delay(1200, cts);
await Delay(1200, ct);
using var ra3 = CaptureToRectArea();
if (Bv.IsInMainUi(ra3))
{
@ -161,7 +161,7 @@ public class TpTask(CancellationTokenSource cts)
{
// 传送点未激活或不存在 按ESC回到大地图界面
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);
await Delay(300, cts);
await Delay(300, ct);
throw;
}
catch (Exception e)
@ -231,14 +231,14 @@ public class TpTask(CancellationTokenSource cts)
var moveUnit = dx > 0 ? 20 : -20;
GameCaptureRegion.GameRegionMove((rect, _) => (rect.Width / 2d + Random.Shared.Next(-rect.Width / 6, rect.Width / 6), rect.Height / 2d + Random.Shared.Next(-rect.Height / 6, rect.Height / 6)));
Simulation.SendInput.Mouse.LeftButtonDown();
await Delay(200, cts);
await Delay(200, ct);
for (var i = 0; i < dx / moveUnit; i++)
{
Simulation.SendInput.Mouse.MoveMouseBy(moveUnit, 0).Sleep(60); // 60 保证没有惯性
}
Simulation.SendInput.Mouse.LeftButtonUp();
await Delay(200, cts);
await Delay(200, ct);
}
public async Task MouseMoveMapY(int dy)
@ -246,7 +246,7 @@ public class TpTask(CancellationTokenSource cts)
var moveUnit = dy > 0 ? 20 : -20;
GameCaptureRegion.GameRegionMove((rect, _) => (rect.Width / 2d + Random.Shared.Next(-rect.Width / 6, rect.Width / 6), rect.Height / 2d + Random.Shared.Next(-rect.Height / 6, rect.Height / 6)));
Simulation.SendInput.Mouse.LeftButtonDown();
await Delay(200, cts);
await Delay(200, ct);
// 原神地图在小范围内移动是无效的,所以先随便移动一下,所以肯定少移动一次
for (var i = 0; i < dy / moveUnit; i++)
{
@ -254,7 +254,7 @@ public class TpTask(CancellationTokenSource cts)
}
Simulation.SendInput.Mouse.LeftButtonUp();
await Delay(200, cts);
await Delay(200, ct);
}
public Point2f GetPositionFromBigMap()
@ -363,7 +363,7 @@ public class TpTask(CancellationTokenSource cts)
if (Bv.BigMapIsUnderground(ra2))
{
ra2.Find(_assets.MapUndergroundToGroundButtonRo).Click();
await Delay(200, cts);
await Delay(200, ct);
}
// 识别当前位置
@ -392,7 +392,7 @@ public class TpTask(CancellationTokenSource cts)
if (minCountry != "当前位置")
{
GameCaptureRegion.GameRegionClick((rect, scale) => (rect.Width - 160 * scale, rect.Height - 60 * scale));
await Delay(300, cts);
await Delay(300, ct);
var ra = CaptureToRectArea();
var list = ra.FindMulti(new RecognitionObject
{
@ -401,7 +401,7 @@ public class TpTask(CancellationTokenSource cts)
});
list.FirstOrDefault(r => r.Text.Length == minCountry.Length && !r.Text.Contains("委托") && r.Text.Contains(minCountry))?.Click();
Logger.LogInformation("切换到区域:{Country}", minCountry);
await Delay(500, cts);
await Delay(500, ct);
return true;
}
@ -442,7 +442,7 @@ public class TpTask(CancellationTokenSource cts)
{
var time = TaskContext.Instance().Config.QuickTeleportConfig.WaitTeleportPanelDelay;
time = time < 300 ? 300 : time;
await Delay(time, cts);
await Delay(time, ct);
if (!CheckTeleportButton(CaptureToRectArea()))
{
// 没传送确认图标说明点开的是未激活传送锚点
@ -514,4 +514,4 @@ public class TpTask(CancellationTokenSource cts)
return hasMapChooseIcon;
}
}
}

View File

@ -1,5 +1,4 @@
using BetterGenshinImpact.Core.Recognition.OCR;
using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.Core.Simulator;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
using BetterGenshinImpact.GameTask.AutoWood.Assets;
@ -8,7 +7,6 @@ using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.GameTask.Model.Area;
using BetterGenshinImpact.Genshin.Settings;
using BetterGenshinImpact.View.Drawable;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
@ -42,7 +40,7 @@ public partial class AutoWoodTask : ISoloTask
private readonly WoodTaskParam _taskParam;
private CancellationTokenSource? _cts;
private CancellationToken _ct;
public AutoWoodTask(WoodTaskParam taskParam)
{
@ -53,11 +51,11 @@ public partial class AutoWoodTask : ISoloTask
_printer = new WoodStatisticsPrinter(_assets);
}
public Task Start(CancellationTokenSource cts)
public Task Start(CancellationToken ct)
{
var runTimeWatch = new Stopwatch();
_cts = cts;
_printer.Cts = _cts;
_ct = ct;
_printer.Ct = _ct;
try
{
@ -106,14 +104,14 @@ public partial class AutoWoodTask : ISoloTask
}
Logger.LogInformation("第{Cnt}次伐木", i + 1);
if (_cts.IsCancellationRequested)
if (_ct.IsCancellationRequested)
{
break;
}
Felling(_taskParam, i + 1 == _taskParam.WoodRoundNum);
VisionContext.Instance().DrawContent.ClearAll();
Sleep(500, _cts);
Sleep(500, _ct);
}
return Task.CompletedTask;
@ -146,7 +144,7 @@ public partial class AutoWoodTask : ISoloTask
"杉木", "竹节", "却砂木", "松木", "萃华木", "桦木", "孔雀木", "梦见木", "御伽木"
];
public CancellationTokenSource? Cts { get; set; }
public CancellationToken Ct { get; set; }
[GeneratedRegex("([^\\d\\n]+)[×x](\\d+)")]
private static partial Regex _parseWoodStatisticsRegex();
@ -217,7 +215,7 @@ public partial class AutoWoodTask : ISoloTask
private void SleepDurationBetweenOcrs(WoodTaskParam taskParam)
{
Sleep(_firstWoodOcr ? 300 : 100, Cts);
Sleep(_firstWoodOcr ? 300 : 100, Ct);
}
private string WoodTextAreaOcr()
@ -433,7 +431,7 @@ public partial class AutoWoodTask : ISoloTask
{
NewRetry.Do(() =>
{
Sleep(1, _cts);
Sleep(1, _ct);
using var contentRegion = CaptureToRectArea();
using var ra = contentRegion.Find(_assets.TheBoonOfTheElderTreeRo);
if (ra.IsEmpty())
@ -447,12 +445,12 @@ public partial class AutoWoodTask : ISoloTask
Simulation.SendInput.Keyboard.KeyPress(_zKey);
Debug.WriteLine("[AutoWood] Z");
Sleep(500, _cts);
Sleep(500, _ct);
}, TimeSpan.FromSeconds(1), 120);
}
Sleep(300, _cts);
Sleep(TaskContext.Instance().Config.AutoWoodConfig.AfterZSleepDelay, _cts);
Sleep(300, _ct);
Sleep(TaskContext.Instance().Config.AutoWoodConfig.AfterZSleepDelay, _ct);
}
private void PressEsc(WoodTaskParam taskParam)
@ -465,13 +463,13 @@ public partial class AutoWoodTask : ISoloTask
// Simulation.SendInput.Keyboard.KeyPress(VK.VK_ESCAPE);
// }
Debug.WriteLine("[AutoWood] Esc");
Sleep(800, _cts);
Sleep(800, _ct);
// 确认在菜单界面
try
{
NewRetry.Do(() =>
{
Sleep(1, _cts);
Sleep(1, _ct);
using var contentRegion = CaptureToRectArea();
using var ra = contentRegion.Find(_assets.MenuBagRo);
if (ra.IsEmpty())
@ -492,7 +490,7 @@ public partial class AutoWoodTask : ISoloTask
Debug.WriteLine("[AutoWood] Click exit button");
Sleep(500, _cts);
Sleep(500, _ct);
// 点击确认
using var contentRegion = CaptureToRectArea();
@ -508,14 +506,14 @@ public partial class AutoWoodTask : ISoloTask
{
if (_login3rdParty.IsAvailabled)
{
Sleep(1, _cts);
_login3rdParty.Login(_cts);
Sleep(1, _ct);
_login3rdParty.Login(_ct);
}
var clickCnt = 0;
for (var i = 0; i < 50; i++)
{
Sleep(1, _cts);
Sleep(1, _ct);
using var contentRegion = CaptureToRectArea();
using var ra = contentRegion.Find(_assets.EnterGameRo);
@ -529,12 +527,12 @@ public partial class AutoWoodTask : ISoloTask
{
if (clickCnt > 2)
{
Sleep(5000, _cts);
Sleep(5000, _ct);
break;
}
}
Sleep(1000, _cts);
Sleep(1000, _ct);
}
if (clickCnt == 0)

View File

@ -76,11 +76,11 @@ internal sealed class Login3rdParty
}
}
public void Login(CancellationTokenSource cts)
public void Login(CancellationToken ct)
{
int failCount = default;
while (!LoginPrivate(cts))
while (!LoginPrivate(ct))
{
// It is necessary to support exitable trying.
// Can exit trying when over than 10s.
@ -90,12 +90,12 @@ internal sealed class Login3rdParty
break;
}
Debug.WriteLine($"[AutoWood] Fail to check login button {failCount} time(s).");
Sleep(500, cts);
Sleep(500, ct);
}
Debug.WriteLine("[AutoWood] Exit while check login button.");
}
private bool LoginPrivate(CancellationTokenSource cts)
private bool LoginPrivate(CancellationToken ct)
{
if (Type == The3rdPartyType.Bilibili)
{
@ -104,7 +104,7 @@ internal sealed class Login3rdParty
if (GetBHWnd(process) != IntPtr.Zero)
{
// Just for login WebUI fadein chattering
Sleep(4000, cts);
Sleep(4000, ct);
var p = TaskContext.Instance()
.SystemInfo.CaptureAreaRect.GetCenterPoint()
@ -114,7 +114,7 @@ internal sealed class Login3rdParty
Debug.WriteLine("[AutoWood] Click login button for the B one");
// Just for login WebUI fadeout chattering
Sleep(3000, cts);
Sleep(3000, ct);
if (GetBHWnd(process) != IntPtr.Zero)
{

View File

@ -39,9 +39,73 @@ public class TaskControl
Thread.Sleep(millisecondsTimeout);
}
public static void Sleep(int millisecondsTimeout, CancellationTokenSource? cts)
// public static void Sleep(int millisecondsTimeout, CancellationTokenSource? cts)
// {
// if (cts is { IsCancellationRequested: true })
// {
// throw new NormalEndException("取消自动任务");
// }
//
// if (millisecondsTimeout <= 0)
// {
// return;
// }
//
// NewRetry.Do(() =>
// {
// if (cts is { IsCancellationRequested: true })
// {
// throw new NormalEndException("取消自动任务");
// }
//
// if (!SystemControl.IsGenshinImpactActiveByProcess())
// {
// Logger.LogInformation("当前获取焦点的窗口不是原神,暂停");
// throw new RetryException("当前获取焦点的窗口不是原神");
// }
// }, TimeSpan.FromSeconds(1), 100);
// Thread.Sleep(millisecondsTimeout);
// if (cts is { IsCancellationRequested: true })
// {
// throw new NormalEndException("取消自动任务");
// }
// }
// public static async Task Delay(int millisecondsTimeout, CancellationTokenSource cts)
// {
// if (cts is { IsCancellationRequested: true })
// {
// throw new NormalEndException("取消自动任务");
// }
//
// if (millisecondsTimeout <= 0)
// {
// return;
// }
//
// NewRetry.Do(() =>
// {
// if (cts is { IsCancellationRequested: true })
// {
// throw new NormalEndException("取消自动任务");
// }
//
// if (!SystemControl.IsGenshinImpactActiveByProcess())
// {
// Logger.LogInformation("当前获取焦点的窗口不是原神,暂停");
// throw new RetryException("当前获取焦点的窗口不是原神");
// }
// }, TimeSpan.FromSeconds(1), 100);
// await Task.Delay(millisecondsTimeout, cts.Token);
// if (cts is { IsCancellationRequested: true })
// {
// throw new NormalEndException("取消自动任务");
// }
// }
public static void Sleep(int millisecondsTimeout, CancellationToken ct)
{
if (cts is { IsCancellationRequested: true })
if (ct.IsCancellationRequested)
{
throw new NormalEndException("取消自动任务");
}
@ -53,7 +117,7 @@ public class TaskControl
NewRetry.Do(() =>
{
if (cts is { IsCancellationRequested: true })
if (ct.IsCancellationRequested)
{
throw new NormalEndException("取消自动任务");
}
@ -65,15 +129,15 @@ public class TaskControl
}
}, TimeSpan.FromSeconds(1), 100);
Thread.Sleep(millisecondsTimeout);
if (cts is { IsCancellationRequested: true })
if (ct.IsCancellationRequested)
{
throw new NormalEndException("取消自动任务");
}
}
public static async Task Delay(int millisecondsTimeout, CancellationTokenSource cts)
public static async Task Delay(int millisecondsTimeout, CancellationToken ct)
{
if (cts is { IsCancellationRequested: true })
if (ct is { IsCancellationRequested: true })
{
throw new NormalEndException("取消自动任务");
}
@ -85,7 +149,7 @@ public class TaskControl
NewRetry.Do(() =>
{
if (cts is { IsCancellationRequested: true })
if (ct is { IsCancellationRequested: true })
{
throw new NormalEndException("取消自动任务");
}
@ -96,8 +160,8 @@ public class TaskControl
throw new RetryException("当前获取焦点的窗口不是原神");
}
}, TimeSpan.FromSeconds(1), 100);
await Task.Delay(millisecondsTimeout, cts.Token);
if (cts is { IsCancellationRequested: true })
await Task.Delay(millisecondsTimeout, ct);
if (ct is { IsCancellationRequested: true })
{
throw new NormalEndException("取消自动任务");
}

View File

@ -5,5 +5,5 @@ namespace BetterGenshinImpact.GameTask;
public interface ISoloTask
{
Task Start(CancellationTokenSource cts);
Task Start(CancellationToken ct);
}

View File

@ -1,26 +0,0 @@
using BetterGenshinImpact.GameTask.Model.Enum;
using System.Threading;
namespace BetterGenshinImpact.GameTask.Model;
/// <summary>
/// 独立任务参数基类
/// </summary>
public class TaskRunnerParam
{
public string Name { get; set; } = string.Empty;
public CancellationTokenSource Cts { get; set; }
/// <summary>
/// 针对实时触发器的操作
/// </summary>
public DispatcherTimerOperationEnum TriggerOperation { get; set; } = DispatcherTimerOperationEnum.None;
public bool UseLock { get; set; }
public TaskRunnerParam(CancellationTokenSource cts)
{
this.Cts = cts;
}
}

View File

@ -102,7 +102,7 @@ public class TaskRunner
public async Task RunSoloTaskAsync(ISoloTask soloTask)
{
await Task.Run(() => RunAsync(async () => await soloTask.Start(CancellationContext.Instance.Cts)));
await Task.Run(() => RunAsync(async () => await soloTask.Start(CancellationContext.Instance.Cts.Token)));
}
public void Init()

View File

@ -465,7 +465,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
Config.HotKeyConfig.RecBigMapPosHotkeyType,
(_, _) =>
{
var p = new TpTask(new CancellationTokenSource()).GetPositionFromBigMap();
var p = new TpTask(new CancellationToken()).GetPositionFromBigMap();
_logger.LogInformation("大地图位置:{Position}", p);
}
));
@ -561,7 +561,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
(_, _) =>
{
NahidaCollectHandler handler = new NahidaCollectHandler();
handler.RunAsync(new CancellationTokenSource());
handler.RunAsync(new CancellationToken());
}
));
debugDirectory.Children.Add(new HotKeySettingModel(