mirror of
https://github.com/babalae/better-genshin-impact
synced 2025-01-09 04:19:47 +08:00
Merge pull request #726 from babalae/feat-cts
refactor: CancellationTokenSource -> CancellationToken
This commit is contained in:
commit
790d42cee0
@ -9,7 +9,7 @@ public class AutoPathingScript(string rootPath)
|
|||||||
public async Task Run(string json)
|
public async Task Run(string json)
|
||||||
{
|
{
|
||||||
var task = PathingTask.BuildFromJson(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)
|
public async Task RunFile(string path)
|
||||||
|
@ -77,7 +77,7 @@ public class Dispatcher
|
|||||||
{
|
{
|
||||||
return;
|
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;
|
break;
|
||||||
|
|
||||||
case "AutoMusicGame":
|
case "AutoMusicGame":
|
||||||
|
@ -37,7 +37,7 @@ public class Genshin
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task Tp(double x, double y)
|
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>
|
/// <summary>
|
||||||
|
@ -137,7 +137,7 @@ public partial class ScriptGroupProject : ObservableObject
|
|||||||
// 加载并执行
|
// 加载并执行
|
||||||
var task = PathingTask.BuildFromFilePath(Path.Combine(MapPathingViewModel.PathJsonPath, FolderName, Name));
|
var task = PathingTask.BuildFromFilePath(Path.Combine(MapPathingViewModel.PathJsonPath, FolderName, Name));
|
||||||
TaskTriggerDispatcher.Instance().AddTrigger("AutoPick", null);
|
TaskTriggerDispatcher.Instance().AddTrigger("AutoPick", null);
|
||||||
await new PathExecutor(CancellationContext.Instance.Cts).Pathing(task);
|
await new PathExecutor(CancellationContext.Instance.Cts.Token).Pathing(task);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using BetterGenshinImpact.Core.Config;
|
using BetterGenshinImpact.Core.Config;
|
||||||
using BetterGenshinImpact.Core.Recognition.OCR;
|
using BetterGenshinImpact.Core.Recognition.OCR;
|
||||||
using BetterGenshinImpact.Core.Recognition.ONNX;
|
using BetterGenshinImpact.Core.Recognition.ONNX;
|
||||||
using BetterGenshinImpact.Core.Script;
|
|
||||||
using BetterGenshinImpact.Core.Simulator;
|
using BetterGenshinImpact.Core.Simulator;
|
||||||
using BetterGenshinImpact.GameTask.AutoFight;
|
using BetterGenshinImpact.GameTask.AutoFight;
|
||||||
using BetterGenshinImpact.GameTask.AutoFight.Assets;
|
using BetterGenshinImpact.GameTask.AutoFight.Assets;
|
||||||
@ -26,7 +25,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Vanara.PInvoke;
|
using Vanara.PInvoke;
|
||||||
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
||||||
using static Vanara.PInvoke.Gdi32;
|
using static Vanara.PInvoke.Kernel32;
|
||||||
using static Vanara.PInvoke.User32;
|
using static Vanara.PInvoke.User32;
|
||||||
|
|
||||||
namespace BetterGenshinImpact.GameTask.AutoDomain;
|
namespace BetterGenshinImpact.GameTask.AutoDomain;
|
||||||
@ -43,7 +42,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
|
|
||||||
private readonly CombatScriptBag _combatScriptBag;
|
private readonly CombatScriptBag _combatScriptBag;
|
||||||
|
|
||||||
private CancellationTokenSource? _cts;
|
private CancellationToken _ct;
|
||||||
|
|
||||||
public AutoDomainTask(AutoDomainParam taskParam)
|
public AutoDomainTask(AutoDomainParam taskParam)
|
||||||
{
|
{
|
||||||
@ -60,9 +59,9 @@ public class AutoDomainTask : ISoloTask
|
|||||||
_combatScriptBag = CombatScriptParser.ReadAndParse(_taskParam.CombatStrategyPath);
|
_combatScriptBag = CombatScriptParser.ReadAndParse(_taskParam.CombatStrategyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Start(CancellationTokenSource cts)
|
public async Task Start(CancellationToken ct)
|
||||||
{
|
{
|
||||||
_cts = cts;
|
_ct = ct;
|
||||||
|
|
||||||
AutoFightAssets.DestroyInstance();
|
AutoFightAssets.DestroyInstance();
|
||||||
Init();
|
Init();
|
||||||
@ -169,7 +168,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
Simulation.SendInput.Keyboard.KeyPress(VK.VK_F);
|
Simulation.SendInput.Keyboard.KeyPress(VK.VK_F);
|
||||||
Logger.LogInformation("自动秘境:{Text}", "进入秘境");
|
Logger.LogInformation("自动秘境:{Text}", "进入秘境");
|
||||||
// 秘境开门动画 5s
|
// 秘境开门动画 5s
|
||||||
Sleep(5000, _cts);
|
Sleep(5000, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
int retryTimes = 0, clickCount = 0;
|
int retryTimes = 0, clickCount = 0;
|
||||||
@ -183,11 +182,11 @@ public class AutoDomainTask : ISoloTask
|
|||||||
clickCount++;
|
clickCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(1500, _cts);
|
Sleep(1500, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 载入动画
|
// 载入动画
|
||||||
Sleep(3000, _cts);
|
Sleep(3000, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseDomainTip()
|
private void CloseDomainTip()
|
||||||
@ -200,16 +199,16 @@ public class AutoDomainTask : ISoloTask
|
|||||||
using var cactRectArea = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.ClickAnyCloseTipRa);
|
using var cactRectArea = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.ClickAnyCloseTipRa);
|
||||||
if (!cactRectArea.IsEmpty())
|
if (!cactRectArea.IsEmpty())
|
||||||
{
|
{
|
||||||
Sleep(1000, _cts);
|
Sleep(1000, _ct);
|
||||||
cactRectArea.Click();
|
cactRectArea.Click();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo 添加小地图角标位置检测 防止有人手点了
|
// todo 添加小地图角标位置检测 防止有人手点了
|
||||||
Sleep(1000, _cts);
|
Sleep(1000, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(1500, _cts);
|
Sleep(1500, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CombatCommand> FindCombatScriptAndSwitchAvatar(CombatScenes combatScenes)
|
private List<CombatCommand> FindCombatScriptAndSwitchAvatar(CombatScenes combatScenes)
|
||||||
@ -226,7 +225,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task WalkToPressF()
|
private async Task WalkToPressF()
|
||||||
{
|
{
|
||||||
if (_cts.Token.IsCancellationRequested)
|
if (_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -243,12 +242,12 @@ public class AutoDomainTask : ISoloTask
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (!_cts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
using var fRectArea = Common.TaskControl.CaptureToRectArea().Find(AutoPickAssets.Instance.FRo);
|
using var fRectArea = Common.TaskControl.CaptureToRectArea().Find(AutoPickAssets.Instance.FRo);
|
||||||
if (fRectArea.IsEmpty())
|
if (fRectArea.IsEmpty())
|
||||||
{
|
{
|
||||||
Sleep(100, _cts);
|
Sleep(100, _ct);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -273,8 +272,8 @@ public class AutoDomainTask : ISoloTask
|
|||||||
private Task StartFight(CombatScenes combatScenes, List<CombatCommand> combatCommands)
|
private Task StartFight(CombatScenes combatScenes, List<CombatCommand> combatCommands)
|
||||||
{
|
{
|
||||||
CancellationTokenSource cts = new();
|
CancellationTokenSource cts = new();
|
||||||
_cts.Token.Register(cts.Cancel);
|
_ct.Register(cts.Cancel);
|
||||||
combatScenes.BeforeTask(cts);
|
combatScenes.BeforeTask(cts.Token);
|
||||||
// 战斗操作
|
// 战斗操作
|
||||||
var combatTask = new Task(() =>
|
var combatTask = new Task(() =>
|
||||||
{
|
{
|
||||||
@ -307,7 +306,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
// 对局结束检测
|
// 对局结束检测
|
||||||
var domainEndTask = DomainEndDetectionTask(cts);
|
var domainEndTask = DomainEndDetectionTask(cts);
|
||||||
// 自动吃药
|
// 自动吃药
|
||||||
var autoEatRecoveryHpTask = AutoEatRecoveryHpTask(cts);
|
var autoEatRecoveryHpTask = AutoEatRecoveryHpTask(cts.Token);
|
||||||
combatTask.Start();
|
combatTask.Start();
|
||||||
domainEndTask.Start();
|
domainEndTask.Start();
|
||||||
autoEatRecoveryHpTask.Start();
|
autoEatRecoveryHpTask.Start();
|
||||||
@ -316,7 +315,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
|
|
||||||
private void EndFightWait()
|
private void EndFightWait()
|
||||||
{
|
{
|
||||||
if (_cts.Token.IsCancellationRequested)
|
if (_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -325,7 +324,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
if (s > 0)
|
if (s > 0)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("战斗结束后等待 {Second} 秒", s);
|
Logger.LogInformation("战斗结束后等待 {Second} 秒", s);
|
||||||
Sleep((int)(s * 1000), _cts);
|
Sleep((int)(s * 1000), _ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +337,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (!_cts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
if (IsDomainEnd())
|
if (IsDomainEnd())
|
||||||
{
|
{
|
||||||
@ -346,7 +345,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Delay(1000, cts);
|
await Delay(1000, cts.Token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -378,7 +377,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task AutoEatRecoveryHpTask(CancellationTokenSource cts)
|
private Task AutoEatRecoveryHpTask(CancellationToken ct)
|
||||||
{
|
{
|
||||||
return new Task(async () =>
|
return new Task(async () =>
|
||||||
{
|
{
|
||||||
@ -394,7 +393,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (!_cts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
if (IsLowHealth())
|
if (IsLowHealth())
|
||||||
{
|
{
|
||||||
@ -404,13 +403,13 @@ public class AutoDomainTask : ISoloTask
|
|||||||
// TODO 吃饱了会一直吃
|
// TODO 吃饱了会一直吃
|
||||||
}
|
}
|
||||||
|
|
||||||
await Delay(500, cts);
|
await Delay(500, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}, cts.Token);
|
}, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsLowHealth()
|
private bool IsLowHealth()
|
||||||
@ -442,10 +441,10 @@ public class AutoDomainTask : ISoloTask
|
|||||||
private Task FindPetrifiedTree()
|
private Task FindPetrifiedTree()
|
||||||
{
|
{
|
||||||
CancellationTokenSource treeCts = new();
|
CancellationTokenSource treeCts = new();
|
||||||
_cts.Token.Register(treeCts.Cancel);
|
_ct.Register(treeCts.Cancel);
|
||||||
// 中键回正视角
|
// 中键回正视角
|
||||||
Simulation.SendInput.Mouse.MiddleButtonClick();
|
Simulation.SendInput.Mouse.MiddleButtonClick();
|
||||||
Sleep(900, _cts);
|
Sleep(900, _ct);
|
||||||
|
|
||||||
// 左右移动直到石化古树位于屏幕中心任务
|
// 左右移动直到石化古树位于屏幕中心任务
|
||||||
var moveAvatarTask = MoveAvatarHorizontallyTask(treeCts);
|
var moveAvatarTask = MoveAvatarHorizontallyTask(treeCts);
|
||||||
@ -467,7 +466,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
var noDetectCount = 0;
|
var noDetectCount = 0;
|
||||||
var prevKey = VK.VK_A;
|
var prevKey = VK.VK_A;
|
||||||
var backwardsAndForwardsCount = 0;
|
var backwardsAndForwardsCount = 0;
|
||||||
while (!_cts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var treeRect = DetectTree(CaptureToRectArea());
|
var treeRect = DetectTree(CaptureToRectArea());
|
||||||
if (treeRect != Rect.Empty)
|
if (treeRect != Rect.Empty)
|
||||||
@ -550,7 +549,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_simulator.KeyPress(VK.VK_W, 60);
|
_simulator.KeyPress(VK.VK_W, 60);
|
||||||
Sleep(500, _cts);
|
Sleep(500, _ct);
|
||||||
treeCts.Cancel();
|
treeCts.Cancel();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -595,12 +594,12 @@ public class AutoDomainTask : ISoloTask
|
|||||||
{
|
{
|
||||||
// 左右移动5次说明已经在树中心了
|
// 左右移动5次说明已经在树中心了
|
||||||
_simulator.KeyPress(VK.VK_W, 60);
|
_simulator.KeyPress(VK.VK_W, 60);
|
||||||
Sleep(500, _cts);
|
Sleep(500, _ct);
|
||||||
treeCts.Cancel();
|
treeCts.Cancel();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(60, _cts);
|
Sleep(60, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
VisionContext.Instance().DrawContent.ClearAll();
|
VisionContext.Instance().DrawContent.ClearAll();
|
||||||
@ -701,7 +700,7 @@ public class AutoDomainTask : ISoloTask
|
|||||||
private bool GettingTreasure(bool recognizeResin, bool isLastTurn)
|
private bool GettingTreasure(bool recognizeResin, bool isLastTurn)
|
||||||
{
|
{
|
||||||
// 等待窗口弹出
|
// 等待窗口弹出
|
||||||
Sleep(1500, _cts);
|
Sleep(1500, _ct);
|
||||||
|
|
||||||
// 优先使用浓缩树脂
|
// 优先使用浓缩树脂
|
||||||
var retryTimes = 0;
|
var retryTimes = 0;
|
||||||
@ -720,22 +719,22 @@ public class AutoDomainTask : ISoloTask
|
|||||||
useCondensedResinRa.Click();
|
useCondensedResinRa.Click();
|
||||||
// 点两下 #224 #218
|
// 点两下 #224 #218
|
||||||
// 解决水龙王按下左键后没松开,然后后续点击按下就没反应了
|
// 解决水龙王按下左键后没松开,然后后续点击按下就没反应了
|
||||||
Sleep(400, _cts);
|
Sleep(400, _ct);
|
||||||
useCondensedResinRa.Click();
|
useCondensedResinRa.Click();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(800, _cts);
|
Sleep(800, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(1000, _cts);
|
Sleep(1000, _ct);
|
||||||
|
|
||||||
var captureArea = TaskContext.Instance().SystemInfo.CaptureAreaRect;
|
var captureArea = TaskContext.Instance().SystemInfo.CaptureAreaRect;
|
||||||
for (var i = 0; i < 30; i++)
|
for (var i = 0; i < 30; i++)
|
||||||
{
|
{
|
||||||
// 跳过领取动画
|
// 跳过领取动画
|
||||||
GameCaptureRegion.GameRegionClick((size, scale) => (size.Width - 140 * scale, 53 * scale));
|
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));
|
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("未检测到秘境结束,可能是背包物品已满。");
|
throw new NormalEndException("未检测到秘境结束,可能是背包物品已满。");
|
||||||
|
@ -21,7 +21,7 @@ public class AutoFightTask : ISoloTask
|
|||||||
|
|
||||||
private readonly CombatScriptBag _combatScriptBag;
|
private readonly CombatScriptBag _combatScriptBag;
|
||||||
|
|
||||||
private CancellationTokenSource? _cts;
|
private CancellationToken _ct;
|
||||||
|
|
||||||
private readonly BgiYoloV8Predictor _predictor;
|
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();
|
LogScreenResolution();
|
||||||
var combatScenes = new CombatScenes().InitializeTeam(CaptureToRectArea());
|
var combatScenes = new CombatScenes().InitializeTeam(CaptureToRectArea());
|
||||||
@ -53,9 +53,9 @@ public class AutoFightTask : ISoloTask
|
|||||||
|
|
||||||
// 新的取消token
|
// 新的取消token
|
||||||
var cts2 = new CancellationTokenSource();
|
var cts2 = new CancellationTokenSource();
|
||||||
cts.Token.Register(cts2.Cancel);
|
ct.Register(cts2.Cancel);
|
||||||
|
|
||||||
combatScenes.BeforeTask(cts2);
|
combatScenes.BeforeTask(cts2.Token);
|
||||||
|
|
||||||
// 战斗操作
|
// 战斗操作
|
||||||
var fightTask = Task.Run(() =>
|
var fightTask = Task.Run(() =>
|
||||||
@ -97,7 +97,7 @@ public class AutoFightTask : ISoloTask
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(1000, cts2);
|
Sleep(1000, cts2.Token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -138,11 +138,11 @@ public class AutoFightTask : ISoloTask
|
|||||||
{
|
{
|
||||||
// 旋转完毕后都没有检测到血条和怪物位置,则按L键确认战斗结束
|
// 旋转完毕后都没有检测到血条和怪物位置,则按L键确认战斗结束
|
||||||
List<int> angles = [0, 90, 180, 270];
|
List<int> angles = [0, 90, 180, 270];
|
||||||
var rotateTask = new CameraRotateTask(_cts!);
|
var rotateTask = new CameraRotateTask(_ct);
|
||||||
foreach (var a in angles)
|
foreach (var a in angles)
|
||||||
{
|
{
|
||||||
await rotateTask.WaitUntilRotatedTo(a, 5, 30);
|
await rotateTask.WaitUntilRotatedTo(a, 5, 30);
|
||||||
await Delay(1000, _cts!); // 等待视角稳定
|
await Delay(1000, _ct!); // 等待视角稳定
|
||||||
if (HasFightFlag(CaptureToRectArea()))
|
if (HasFightFlag(CaptureToRectArea()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -72,7 +72,7 @@ public class Avatar
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 任务取消令牌
|
/// 任务取消令牌
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CancellationTokenSource? Cts { get; set; }
|
public CancellationToken Ct { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 战斗场景
|
/// 战斗场景
|
||||||
@ -106,7 +106,7 @@ public class Avatar
|
|||||||
if (!confirmRectArea.IsEmpty())
|
if (!confirmRectArea.IsEmpty())
|
||||||
{
|
{
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);
|
||||||
Sleep(600, Cts);
|
Sleep(600, Ct);
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_M);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_M);
|
||||||
throw new Exception("存在角色被击败,按 M 键打开地图,并停止自动秘境。");
|
throw new Exception("存在角色被击败,按 M 键打开地图,并停止自动秘境。");
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ public class Avatar
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < 30; i++)
|
for (var i = 0; i < 30; i++)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ public class Avatar
|
|||||||
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_1 + (byte)Index - 1);
|
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_1 + (byte)Index - 1);
|
||||||
// Debug.WriteLine($"切换到{Index}号位");
|
// Debug.WriteLine($"切换到{Index}号位");
|
||||||
// Cv2.ImWrite($"log/切换.png", content.CaptureRectArea.SrcMat);
|
// Cv2.ImWrite($"log/切换.png", content.CaptureRectArea.SrcMat);
|
||||||
Sleep(250, Cts);
|
Sleep(250, Ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,14 +248,14 @@ public class Avatar
|
|||||||
{
|
{
|
||||||
while (ms >= 0)
|
while (ms >= 0)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoFightContext.Instance.Simulator.LeftButtonClick();
|
AutoFightContext.Instance.Simulator.LeftButtonClick();
|
||||||
ms -= 200;
|
ms -= 200;
|
||||||
Sleep(200, Cts);
|
Sleep(200, Ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ public class Avatar
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < 1; i++)
|
for (var i = 0; i < 1; i++)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ public class Avatar
|
|||||||
if (Name == "纳西妲")
|
if (Name == "纳西妲")
|
||||||
{
|
{
|
||||||
AutoFightContext.Instance.Simulator.KeyDown(User32.VK.VK_E);
|
AutoFightContext.Instance.Simulator.KeyDown(User32.VK.VK_E);
|
||||||
Sleep(300, Cts);
|
Sleep(300, Ct);
|
||||||
for (int j = 0; j < 10; j++)
|
for (int j = 0; j < 10; j++)
|
||||||
{
|
{
|
||||||
Simulation.SendInput.Mouse.MoveMouseBy(1000, 0);
|
Simulation.SendInput.Mouse.MoveMouseBy(1000, 0);
|
||||||
@ -296,7 +296,7 @@ public class Avatar
|
|||||||
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_E);
|
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_E);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(200, Cts);
|
Sleep(200, Ct);
|
||||||
|
|
||||||
var region = CaptureToRectArea();
|
var region = CaptureToRectArea();
|
||||||
ThrowWhenDefeated(region);
|
ThrowWhenDefeated(region);
|
||||||
@ -331,13 +331,13 @@ public class Avatar
|
|||||||
// var isBurstReleased = false;
|
// var isBurstReleased = false;
|
||||||
for (var i = 0; i < 10; i++)
|
for (var i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_Q);
|
AutoFightContext.Instance.Simulator.KeyPress(User32.VK.VK_Q);
|
||||||
Sleep(200, Cts);
|
Sleep(200, Ct);
|
||||||
|
|
||||||
var region = CaptureToRectArea();
|
var region = CaptureToRectArea();
|
||||||
ThrowWhenDefeated(region);
|
ThrowWhenDefeated(region);
|
||||||
@ -345,7 +345,7 @@ public class Avatar
|
|||||||
if (notActiveCount == 0)
|
if (notActiveCount == 0)
|
||||||
{
|
{
|
||||||
// isBurstReleased = true;
|
// isBurstReleased = true;
|
||||||
Sleep(1500, Cts);
|
Sleep(1500, Ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
@ -381,7 +381,7 @@ public class Avatar
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dash(int ms = 0)
|
public void Dash(int ms = 0)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@ public class Avatar
|
|||||||
|
|
||||||
public void Walk(string key, int ms)
|
public void Walk(string key, int ms)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -473,7 +473,7 @@ public class Avatar
|
|||||||
AutoFightContext.Instance.Simulator.LeftButtonDown();
|
AutoFightContext.Instance.Simulator.LeftButtonDown();
|
||||||
while (ms >= 0)
|
while (ms >= 0)
|
||||||
{
|
{
|
||||||
if (Cts is { IsCancellationRequested: true })
|
if (Ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -188,11 +188,11 @@ public class CombatScenes : IDisposable
|
|||||||
return avatars;
|
return avatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeforeTask(CancellationTokenSource cts)
|
public void BeforeTask(CancellationToken ct)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < AvatarCount; i++)
|
for (var i = 0; i < AvatarCount; i++)
|
||||||
{
|
{
|
||||||
Avatars[i].Cts = cts;
|
Avatars[i].Ct = ct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
|
|||||||
if (_cts == null || _cts.Token.IsCancellationRequested)
|
if (_cts == null || _cts.Token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
_fightTask = FightTask(_cts);
|
_fightTask = FightTask(_cts.Token);
|
||||||
if (!_fightTask.IsCompleted)
|
if (!_fightTask.IsCompleted)
|
||||||
{
|
{
|
||||||
_fightTask.Start();
|
_fightTask.Start();
|
||||||
@ -65,7 +65,7 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
|
|||||||
if (_cts == null || _cts.Token.IsCancellationRequested)
|
if (_cts == null || _cts.Token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
_fightTask = FightTask(_cts);
|
_fightTask = FightTask(_cts.Token);
|
||||||
if (!_fightTask.IsCompleted)
|
if (!_fightTask.IsCompleted)
|
||||||
{
|
{
|
||||||
_fightTask.Start();
|
_fightTask.Start();
|
||||||
@ -126,14 +126,14 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 循环执行战斗宏
|
/// 循环执行战斗宏
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Task FightTask(CancellationTokenSource cts)
|
private Task FightTask(CancellationToken ct)
|
||||||
{
|
{
|
||||||
// 切换截图模式
|
// 切换截图模式
|
||||||
var dispatcherCaptureMode = TaskTriggerDispatcher.Instance().GetCacheCaptureMode();
|
var dispatcherCaptureMode = TaskTriggerDispatcher.Instance().GetCacheCaptureMode();
|
||||||
if (dispatcherCaptureMode != DispatcherCaptureModeEnum.CacheCaptureWithTrigger)
|
if (dispatcherCaptureMode != DispatcherCaptureModeEnum.CacheCaptureWithTrigger)
|
||||||
{
|
{
|
||||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||||
Sleep(TaskContext.Instance().Config.TriggerInterval * 2, cts); // 等待缓存图像
|
Sleep(TaskContext.Instance().Config.TriggerInterval * 2, ct); // 等待缓存图像
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageRegion = CaptureToRectArea();
|
var imageRegion = CaptureToRectArea();
|
||||||
@ -162,7 +162,7 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
|
|||||||
return new Task(() =>
|
return new Task(() =>
|
||||||
{
|
{
|
||||||
Logger.LogInformation("→ {Name}执行宏", activeAvatar.Name);
|
Logger.LogInformation("→ {Name}执行宏", activeAvatar.Name);
|
||||||
while (!cts.Token.IsCancellationRequested && IsEnabled())
|
while (!ct.IsCancellationRequested && IsEnabled())
|
||||||
{
|
{
|
||||||
if (IsHoldOnMode() && !_isKeyDown)
|
if (IsHoldOnMode() && !_isKeyDown)
|
||||||
{
|
{
|
||||||
|
@ -5,11 +5,11 @@ namespace BetterGenshinImpact.GameTask.AutoGeniusInvokation;
|
|||||||
|
|
||||||
public class AutoGeniusInvokationTask(GeniusInvokationTaskParam taskParam) : ISoloTask
|
public class AutoGeniusInvokationTask(GeniusInvokationTaskParam taskParam) : ISoloTask
|
||||||
{
|
{
|
||||||
public Task Start(CancellationTokenSource cts)
|
public Task Start(CancellationToken ct)
|
||||||
{
|
{
|
||||||
// 读取策略信息
|
// 读取策略信息
|
||||||
var duel = ScriptParser.Parse(taskParam.StrategyContent);
|
var duel = ScriptParser.Parse(taskParam.StrategyContent);
|
||||||
duel.Run(cts);
|
duel.Run(ct);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,15 +61,15 @@ public class GeniusInvokationControl
|
|||||||
|
|
||||||
public static bool OutputImageWhenError = true;
|
public static bool OutputImageWhenError = true;
|
||||||
|
|
||||||
private CancellationTokenSource? _cts;
|
private CancellationToken _ct;
|
||||||
|
|
||||||
private readonly AutoGeniusInvokationAssets _assets = AutoGeniusInvokationAssets.Instance;
|
private readonly AutoGeniusInvokationAssets _assets = AutoGeniusInvokationAssets.Instance;
|
||||||
|
|
||||||
// private IGameCapture? _gameCapture;
|
// private IGameCapture? _gameCapture;
|
||||||
|
|
||||||
public void Init(CancellationTokenSource cts)
|
public void Init(CancellationToken ct)
|
||||||
{
|
{
|
||||||
_cts = cts;
|
_ct = ct;
|
||||||
// _gameCapture = taskParam.Dispatcher.GameCapture;
|
// _gameCapture = taskParam.Dispatcher.GameCapture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ public class GeniusInvokationControl
|
|||||||
{
|
{
|
||||||
NewRetry.Do(() =>
|
NewRetry.Do(() =>
|
||||||
{
|
{
|
||||||
if (_cts is { IsCancellationRequested: true })
|
if (_ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ public class GeniusInvokationControl
|
|||||||
}
|
}
|
||||||
}, TimeSpan.FromSeconds(1), 100);
|
}, TimeSpan.FromSeconds(1), 100);
|
||||||
|
|
||||||
if (_cts is { IsCancellationRequested: true })
|
if (_ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
throw new TaskCanceledException("任务取消");
|
throw new TaskCanceledException("任务取消");
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
using BetterGenshinImpact.Core.Recognition.OpenCv;
|
using BetterGenshinImpact.Core.Recognition.OpenCv;
|
||||||
using BetterGenshinImpact.Core.Script;
|
|
||||||
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Assets;
|
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Assets;
|
||||||
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
|
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
|
||||||
using BetterGenshinImpact.GameTask.Common;
|
using BetterGenshinImpact.GameTask.Common;
|
||||||
using BetterGenshinImpact.Service.Notification;
|
using BetterGenshinImpact.Service.Notification;
|
||||||
using BetterGenshinImpact.View.Drawable;
|
using BetterGenshinImpact.View.Drawable;
|
||||||
using BetterGenshinImpact.ViewModel.Pages;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using System;
|
using System;
|
||||||
@ -50,25 +48,22 @@ public class Duel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentDiceCount { get; set; } = 0;
|
public int CurrentDiceCount { get; set; } = 0;
|
||||||
|
|
||||||
public CancellationTokenSource Cts { get; set; } = default!;
|
|
||||||
|
|
||||||
private int _keqingECount = 0;
|
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
|
try
|
||||||
{
|
{
|
||||||
AutoGeniusInvokationAssets.DestroyInstance();
|
AutoGeniusInvokationAssets.DestroyInstance();
|
||||||
|
|
||||||
LogScreenResolution();
|
LogScreenResolution();
|
||||||
NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Started().Build()); // TODO 需要移动
|
NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Started().Build()); // TODO 需要移动
|
||||||
GeniusInvokationControl.GetInstance().Init(Cts);
|
GeniusInvokationControl.GetInstance().Init(ct);
|
||||||
|
|
||||||
// 对局准备 选择初始手牌
|
// 对局准备 选择初始手牌
|
||||||
GeniusInvokationControl.GetInstance().CommonDuelPrepare();
|
GeniusInvokationControl.GetInstance().CommonDuelPrepare();
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using BetterGenshinImpact.Core.Script;
|
using BetterGenshinImpact.Core.Simulator;
|
||||||
using BetterGenshinImpact.Core.Simulator;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using System;
|
using System;
|
||||||
@ -28,7 +27,7 @@ public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
|
|||||||
|
|
||||||
private readonly IntPtr _hWnd = TaskContext.Instance().GameHandle;
|
private readonly IntPtr _hWnd = TaskContext.Instance().GameHandle;
|
||||||
|
|
||||||
public Task Start(CancellationTokenSource cts)
|
public Task Start(CancellationToken ct)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
@ -43,16 +42,16 @@ public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
|
|||||||
{
|
{
|
||||||
var (x, y) = gameCaptureRegion.ConvertPositionToGameCaptureRegion((int)(keyValuePair.Value * assetScale), (int)(_keyY * assetScale));
|
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]);
|
Task.WaitAll([.. taskList]);
|
||||||
return Task.CompletedTask;
|
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);
|
Thread.Sleep(10);
|
||||||
// Stopwatch sw = new();
|
// Stopwatch sw = new();
|
||||||
@ -64,7 +63,7 @@ public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
|
|||||||
if (c.B < 220)
|
if (c.B < 220)
|
||||||
{
|
{
|
||||||
KeyDown(key);
|
KeyDown(key);
|
||||||
while (!cts.Token.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
Thread.Sleep(10);
|
Thread.Sleep(10);
|
||||||
hdc = User32.GetDC(_hWnd);
|
hdc = User32.GetDC(_hWnd);
|
||||||
|
@ -9,7 +9,7 @@ using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
|||||||
|
|
||||||
namespace BetterGenshinImpact.GameTask.AutoPathing;
|
namespace BetterGenshinImpact.GameTask.AutoPathing;
|
||||||
|
|
||||||
public class CameraRotateTask(CancellationTokenSource cts)
|
public class CameraRotateTask(CancellationToken ct)
|
||||||
{
|
{
|
||||||
private readonly double _dpi = TaskContext.Instance().DpiScale;
|
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)
|
public async Task WaitUntilRotatedTo(int targetOrientation, int maxDiff, int maxTryTimes = 50)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (!cts.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var screen = CaptureToRectArea();
|
var screen = CaptureToRectArea();
|
||||||
if (Math.Abs(RotateToApproach(targetOrientation, screen)) < maxDiff)
|
if (Math.Abs(RotateToApproach(targetOrientation, screen)) < maxDiff)
|
||||||
@ -73,7 +73,7 @@ public class CameraRotateTask(CancellationTokenSource cts)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Delay(50, cts);
|
await Delay(50, ct);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,12 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
|
|||||||
|
|
||||||
internal class AutoFightHandler : IActionHandler
|
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}", "自动战斗");
|
TaskControl.Logger.LogInformation("执行 {Text}", "自动战斗");
|
||||||
// 爷们要战斗
|
// 爷们要战斗
|
||||||
@ -26,7 +26,7 @@ internal class AutoFightHandler : IActionHandler
|
|||||||
PickDropsAfterFightEnabled = true
|
PickDropsAfterFightEnabled = true
|
||||||
};
|
};
|
||||||
var fightSoloTask = new AutoFightTask(taskParams);
|
var fightSoloTask = new AutoFightTask(taskParams);
|
||||||
await fightSoloTask.Start(cts);
|
await fightSoloTask.Start(ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetFightStrategy()
|
private string GetFightStrategy()
|
||||||
|
@ -13,7 +13,7 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ElementalSkillHandler : IActionHandler
|
public class ElementalSkillHandler : IActionHandler
|
||||||
{
|
{
|
||||||
public Task RunAsync(CancellationTokenSource cts)
|
public Task RunAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TaskControl.Logger.LogInformation("执行 {Text}", "释放元素战技");
|
TaskControl.Logger.LogInformation("执行 {Text}", "释放元素战技");
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_E);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_E);
|
||||||
|
@ -5,5 +5,5 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
|
|||||||
|
|
||||||
public interface IActionHandler
|
public interface IActionHandler
|
||||||
{
|
{
|
||||||
Task RunAsync(CancellationTokenSource cts);
|
Task RunAsync(CancellationToken ct);
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,13 @@ public class NahidaCollectHandler : IActionHandler
|
|||||||
{
|
{
|
||||||
private DateTime lastETime = DateTime.MinValue;
|
private DateTime lastETime = DateTime.MinValue;
|
||||||
|
|
||||||
public async Task RunAsync(CancellationTokenSource cts)
|
public async Task RunAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("执行 {Nhd} 长按E转圈拾取", "纳西妲");
|
Logger.LogInformation("执行 {Nhd} 长按E转圈拾取", "纳西妲");
|
||||||
var cd = DateTime.Now - lastETime;
|
var cd = DateTime.Now - lastETime;
|
||||||
if (cd < TimeSpan.FromSeconds(10))
|
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;
|
var dpi = TaskContext.Instance().DpiScale;
|
||||||
@ -30,21 +30,21 @@ public class NahidaCollectHandler : IActionHandler
|
|||||||
int i = 60;
|
int i = 60;
|
||||||
// 视角拉到最下面
|
// 视角拉到最下面
|
||||||
Simulation.SendInput.Mouse.MoveMouseBy(0, 10000);
|
Simulation.SendInput.Mouse.MoveMouseBy(0, 10000);
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
|
|
||||||
// 按住E技能 无死角扫码
|
// 按住E技能 无死角扫码
|
||||||
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_E);
|
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_E);
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
|
|
||||||
// 先地面来一圈
|
// 先地面来一圈
|
||||||
for (int j = 0; j < 15; j++)
|
for (int j = 0; j < 15; j++)
|
||||||
{
|
{
|
||||||
Simulation.SendInput.Mouse.MoveMouseBy(x, 500);
|
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--;
|
i--;
|
||||||
if (i == 40)
|
if (i == 40)
|
||||||
@ -53,17 +53,17 @@ public class NahidaCollectHandler : IActionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
Simulation.SendInput.Mouse.MoveMouseBy(x, y);
|
Simulation.SendInput.Mouse.MoveMouseBy(x, y);
|
||||||
await Delay(30, cts);
|
await Delay(30, ct);
|
||||||
}
|
}
|
||||||
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_E);
|
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_E);
|
||||||
|
|
||||||
lastETime = DateTime.Now;
|
lastETime = DateTime.Now;
|
||||||
|
|
||||||
await Delay(1000, cts);
|
await Delay(1000, ct);
|
||||||
|
|
||||||
// 恢复视角
|
// 恢复视角
|
||||||
Simulation.SendInput.Mouse.MiddleButtonClick();
|
Simulation.SendInput.Mouse.MiddleButtonClick();
|
||||||
|
|
||||||
await Delay(1000, cts);
|
await Delay(1000, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class NormalAttackHandler : IActionHandler
|
public class NormalAttackHandler : IActionHandler
|
||||||
{
|
{
|
||||||
public Task RunAsync(CancellationTokenSource cts)
|
public Task RunAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TaskControl.Logger.LogInformation("执行 {Text}", "普通攻击");
|
TaskControl.Logger.LogInformation("执行 {Text}", "普通攻击");
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PickAroundHandler : IActionHandler
|
public class PickAroundHandler : IActionHandler
|
||||||
{
|
{
|
||||||
public async Task RunAsync(CancellationTokenSource cts)
|
public async Task RunAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
var screen = CaptureToRectArea();
|
var screen = CaptureToRectArea();
|
||||||
var angle = 0;
|
var angle = 0;
|
||||||
CameraRotateTask rotateTask = new(cts);
|
CameraRotateTask rotateTask = new(ct);
|
||||||
TaskControl.Logger.LogInformation("执行 {Text}", "小范围内自动拾取");
|
TaskControl.Logger.LogInformation("执行 {Text}", "小范围内自动拾取");
|
||||||
await rotateTask.WaitUntilRotatedTo(angle, 5);
|
await rotateTask.WaitUntilRotatedTo(angle, 5);
|
||||||
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
||||||
@ -29,7 +29,7 @@ public class PickAroundHandler : IActionHandler
|
|||||||
rotateTask.RotateToApproach(angle, screen);
|
rotateTask.RotateToApproach(angle, screen);
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_F);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_F);
|
||||||
await Delay(100, cts);
|
await Delay(100, ct);
|
||||||
if (DateTime.UtcNow - startTime > TimeSpan.FromSeconds(5))
|
if (DateTime.UtcNow - startTime > TimeSpan.FromSeconds(5))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
|||||||
|
|
||||||
namespace BetterGenshinImpact.GameTask.AutoPathing;
|
namespace BetterGenshinImpact.GameTask.AutoPathing;
|
||||||
|
|
||||||
public class PathExecutor(CancellationTokenSource cts)
|
public class PathExecutor(CancellationToken ct)
|
||||||
{
|
{
|
||||||
private readonly CameraRotateTask _rotateTask = new(cts);
|
private readonly CameraRotateTask _rotateTask = new(ct);
|
||||||
private readonly TrapEscaper _trapEscaper = new(cts);
|
private readonly TrapEscaper _trapEscaper = new(ct);
|
||||||
|
|
||||||
public async Task Pathing(PathingTask task)
|
public async Task Pathing(PathingTask task)
|
||||||
{
|
{
|
||||||
@ -37,7 +37,7 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
|
|
||||||
var waypoints = ConvertWaypointsForTrack(task.Positions);
|
var waypoints = ConvertWaypointsForTrack(task.Positions);
|
||||||
|
|
||||||
await Delay(100, cts);
|
await Delay(100, ct);
|
||||||
Navigation.WarmUp(); // 提前加载地图特征点
|
Navigation.WarmUp(); // 提前加载地图特征点
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -85,7 +85,7 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
private async Task HandleTeleportWaypoint(WaypointForTrack waypoint)
|
private async Task HandleTeleportWaypoint(WaypointForTrack waypoint)
|
||||||
{
|
{
|
||||||
var forceTp = waypoint.Action == ActionEnum.ForceTp.Code;
|
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);
|
var (tprX, tprY) = MapCoordinate.GameToMain2048(tpX, tpY);
|
||||||
EntireMap.Instance.SetPrevPosition((float)tprX, (float)tprY); // 通过上一个位置直接进行局部特征匹配
|
EntireMap.Instance.SetPrevPosition((float)tprX, (float)tprY); // 通过上一个位置直接进行局部特征匹配
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
|
|
||||||
// 按下w,一直走
|
// 按下w,一直走
|
||||||
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
||||||
while (!cts.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
if ((now - startTime).TotalSeconds > 240)
|
if ((now - startTime).TotalSeconds > 240)
|
||||||
@ -168,7 +168,7 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
{
|
{
|
||||||
Debug.WriteLine("未进入飞行状态,按下空格");
|
Debug.WriteLine("未进入飞行状态,按下空格");
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -177,7 +177,7 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
if (waypoint.MoveMode == MoveModeEnum.Jump.Code)
|
if (waypoint.MoveMode == MoveModeEnum.Jump.Code)
|
||||||
{
|
{
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Delay(100, cts);
|
await Delay(100, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 抬起w键
|
// 抬起w键
|
||||||
@ -228,12 +228,12 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
//下落攻击接近目的地
|
//下落攻击接近目的地
|
||||||
Logger.LogInformation("动作:下落攻击");
|
Logger.LogInformation("动作:下落攻击");
|
||||||
Simulation.SendInput.Mouse.LeftButtonClick();
|
Simulation.SendInput.Mouse.LeftButtonClick();
|
||||||
await Delay(1000, cts);
|
await Delay(1000, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2);
|
await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2);
|
||||||
var stepsTaken = 0;
|
var stepsTaken = 0;
|
||||||
while (!cts.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
stepsTaken++;
|
stepsTaken++;
|
||||||
if (stepsTaken > 20)
|
if (stepsTaken > 20)
|
||||||
@ -254,13 +254,13 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2);
|
await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2);
|
||||||
// 小碎步接近
|
// 小碎步接近
|
||||||
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W).Sleep(60).KeyUp(User32.VK.VK_W);
|
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);
|
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W);
|
||||||
|
|
||||||
// 到达目的地后停顿一秒
|
// 到达目的地后停顿一秒
|
||||||
await Delay(1000, cts);
|
await Delay(1000, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AfterMoveToTarget(Waypoint waypoint)
|
private async Task AfterMoveToTarget(Waypoint waypoint)
|
||||||
@ -270,8 +270,8 @@ public class PathExecutor(CancellationTokenSource cts)
|
|||||||
|| waypoint.Action == ActionEnum.Fight.Code)
|
|| waypoint.Action == ActionEnum.Fight.Code)
|
||||||
{
|
{
|
||||||
var handler = ActionFactory.GetHandler(waypoint.Action);
|
var handler = ActionFactory.GetHandler(waypoint.Action);
|
||||||
await handler.RunAsync(cts);
|
await handler.RunAsync(ct);
|
||||||
await Delay(800, cts);
|
await Delay(800, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@ using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
|||||||
|
|
||||||
namespace BetterGenshinImpact.GameTask.AutoPathing;
|
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 static readonly Random _random = new Random();
|
||||||
private int _lastActionIndex = 0;
|
private int _lastActionIndex = 0;
|
||||||
public static DateTime LastActionTime = DateTime.UtcNow;
|
public static DateTime LastActionTime = DateTime.UtcNow;
|
||||||
@ -39,7 +39,7 @@ public class TrapEscaper(CancellationTokenSource cts)
|
|||||||
|
|
||||||
// 按下w,一直走
|
// 按下w,一直走
|
||||||
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
Simulation.SendInput.Keyboard.KeyDown(User32.VK.VK_W);
|
||||||
while (!cts.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
if ((now - LastActionTime).TotalSeconds > 5)
|
if ((now - LastActionTime).TotalSeconds > 5)
|
||||||
@ -106,7 +106,7 @@ public class TrapEscaper(CancellationTokenSource cts)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Delay(100, cts);
|
await Delay(100, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 抬起w键
|
// 抬起w键
|
||||||
@ -119,9 +119,9 @@ public class TrapEscaper(CancellationTokenSource cts)
|
|||||||
// 脱离攀爬状态
|
// 脱离攀爬状态
|
||||||
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W);
|
Simulation.SendInput.Keyboard.KeyUp(User32.VK.VK_W);
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_X);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_X);
|
||||||
await Delay(75, cts);
|
await Delay(75, ct);
|
||||||
Simulation.SendInput.Mouse.LeftButtonClick();
|
Simulation.SendInput.Mouse.LeftButtonClick();
|
||||||
await Delay(500, cts);
|
await Delay(500, ct);
|
||||||
|
|
||||||
TimeSpan timeSinceLastAction = DateTime.UtcNow - LastActionTime;
|
TimeSpan timeSinceLastAction = DateTime.UtcNow - LastActionTime;
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ using BetterGenshinImpact.GameTask.Model.Area;
|
|||||||
using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
|
using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
|
||||||
using BetterGenshinImpact.Helpers;
|
using BetterGenshinImpact.Helpers;
|
||||||
using BetterGenshinImpact.View.Drawable;
|
using BetterGenshinImpact.View.Drawable;
|
||||||
using BetterGenshinImpact.ViewModel.Pages;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using System;
|
using System;
|
||||||
@ -38,7 +37,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private Rect _missionDistanceRect = Rect.Empty;
|
private Rect _missionDistanceRect = Rect.Empty;
|
||||||
|
|
||||||
private CancellationTokenSource? _cts;
|
private CancellationToken _ct;
|
||||||
|
|
||||||
public async void Start()
|
public async void Start()
|
||||||
{
|
{
|
||||||
@ -56,7 +55,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
|
|
||||||
Logger.LogInformation("→ {Text}", "自动追踪,启动!");
|
Logger.LogInformation("→ {Text}", "自动追踪,启动!");
|
||||||
|
|
||||||
_cts = CancellationContext.Instance.Cts;
|
_ct = CancellationContext.Instance.Cts.Token;
|
||||||
|
|
||||||
TrackMission();
|
TrackMission();
|
||||||
}
|
}
|
||||||
@ -90,20 +89,20 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
var paimonMenuRa = ra.Find(ElementAssets.Instance.PaimonMenuRo);
|
var paimonMenuRa = ra.Find(ElementAssets.Instance.PaimonMenuRo);
|
||||||
if (!paimonMenuRa.IsExist())
|
if (!paimonMenuRa.IsExist())
|
||||||
{
|
{
|
||||||
Sleep(5000, _cts);
|
Sleep(5000, _ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 任务文字有动效,等待2s重新截图
|
// 任务文字有动效,等待2s重新截图
|
||||||
Simulation.SendInput.Mouse.MoveMouseBy(0, 7000);
|
Simulation.SendInput.Mouse.MoveMouseBy(0, 7000);
|
||||||
Sleep(2000, _cts);
|
Sleep(2000, _ct);
|
||||||
|
|
||||||
// OCR 任务文字 在小地图下方
|
// OCR 任务文字 在小地图下方
|
||||||
var textRaList = OcrMissionTextRaList(paimonMenuRa);
|
var textRaList = OcrMissionTextRaList(paimonMenuRa);
|
||||||
if (textRaList.Count == 0)
|
if (textRaList.Count == 0)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("未找到任务文字");
|
Logger.LogInformation("未找到任务文字");
|
||||||
Sleep(5000, _cts);
|
Sleep(5000, _ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,14 +114,14 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
// 距离大于150米,先传送到最近的传送点
|
// 距离大于150米,先传送到最近的传送点
|
||||||
// J 打开任务 切换追踪打开地图 中心点就是任务点
|
// J 打开任务 切换追踪打开地图 中心点就是任务点
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_J);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_J);
|
||||||
Sleep(800, _cts);
|
Sleep(800, _ct);
|
||||||
// TODO 识别是否在任务界面
|
// TODO 识别是否在任务界面
|
||||||
// 切换追踪
|
// 切换追踪
|
||||||
var btn = ra.Derive(CaptureRect.Width - 250, CaptureRect.Height - 60);
|
var btn = ra.Derive(CaptureRect.Width - 250, CaptureRect.Height - 60);
|
||||||
btn.Click();
|
btn.Click();
|
||||||
Sleep(200, _cts);
|
Sleep(200, _ct);
|
||||||
btn.Click();
|
btn.Click();
|
||||||
Sleep(1500, _cts);
|
Sleep(1500, _ct);
|
||||||
|
|
||||||
// 寻找所有传送点
|
// 寻找所有传送点
|
||||||
ra = CaptureToRectArea();
|
ra = CaptureToRectArea();
|
||||||
@ -146,7 +145,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
|
|
||||||
ra.Derive(nearestRect).Click();
|
ra.Derive(nearestRect).Click();
|
||||||
// 等待自动传送完成
|
// 等待自动传送完成
|
||||||
Sleep(2000, _cts);
|
Sleep(2000, _ct);
|
||||||
|
|
||||||
if (Bv.IsInBigMapUi(CaptureToRectArea()))
|
if (Bv.IsInBigMapUi(CaptureToRectArea()))
|
||||||
{
|
{
|
||||||
@ -154,7 +153,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Sleep(500, _cts);
|
Sleep(500, _ct);
|
||||||
NewRetry.Do(() =>
|
NewRetry.Do(() =>
|
||||||
{
|
{
|
||||||
if (!Bv.IsInMainUi(CaptureToRectArea()))
|
if (!Bv.IsInMainUi(CaptureToRectArea()))
|
||||||
@ -181,7 +180,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
{
|
{
|
||||||
// V键直接追踪
|
// V键直接追踪
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_V);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_V);
|
||||||
Sleep(3000, _cts);
|
Sleep(3000, _ct);
|
||||||
|
|
||||||
var ra = CaptureToRectArea();
|
var ra = CaptureToRectArea();
|
||||||
var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
|
var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
|
||||||
@ -204,7 +203,7 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask
|
|||||||
// {
|
// {
|
||||||
int prevMoveX = 0;
|
int prevMoveX = 0;
|
||||||
bool wDown = false;
|
bool wDown = false;
|
||||||
while (!_cts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var ra = CaptureToRectArea();
|
var ra = CaptureToRectArea();
|
||||||
var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
|
var blueTrackPointRa = ra.Find(ElementAssets.Instance.BlueTrackPoint);
|
||||||
|
@ -13,7 +13,6 @@ using BetterGenshinImpact.Helpers;
|
|||||||
using BetterGenshinImpact.Helpers.Extensions;
|
using BetterGenshinImpact.Helpers.Extensions;
|
||||||
using BetterGenshinImpact.Service;
|
using BetterGenshinImpact.Service;
|
||||||
using BetterGenshinImpact.View.Drawable;
|
using BetterGenshinImpact.View.Drawable;
|
||||||
using BetterGenshinImpact.ViewModel.Pages;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using System;
|
using System;
|
||||||
@ -45,7 +44,7 @@ public class AutoTrackPathTask
|
|||||||
// 视角偏移移动单位
|
// 视角偏移移动单位
|
||||||
private const int CharMovingUnit = 500;
|
private const int CharMovingUnit = 500;
|
||||||
|
|
||||||
private CancellationTokenSource? _cts;
|
private CancellationToken _ct;
|
||||||
|
|
||||||
public AutoTrackPathTask(AutoTrackPathParam taskParam)
|
public AutoTrackPathTask(AutoTrackPathParam taskParam)
|
||||||
{
|
{
|
||||||
@ -67,7 +66,7 @@ public class AutoTrackPathTask
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cts = CancellationContext.Instance.Cts;
|
_ct = CancellationContext.Instance.Cts.Token;
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
@ -102,19 +101,14 @@ public class AutoTrackPathTask
|
|||||||
SystemControl.ActivateWindow();
|
SystemControl.ActivateWindow();
|
||||||
Logger.LogInformation("→ {Text}", "自动路线,启动!");
|
Logger.LogInformation("→ {Text}", "自动路线,启动!");
|
||||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
|
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
|
||||||
Sleep(TaskContext.Instance().Config.TriggerInterval * 5, _cts); // 等待缓存图像
|
Sleep(TaskContext.Instance().Config.TriggerInterval * 5, _ct); // 等待缓存图像
|
||||||
}
|
|
||||||
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
_cts.Cancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DoTask()
|
public async Task DoTask()
|
||||||
{
|
{
|
||||||
// 1. 传送到最近的传送点
|
// 1. 传送到最近的传送点
|
||||||
var first = _way.WayPointList[0]; // 解析路线,第一个点为起点
|
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. 等待传送完成
|
// 2. 等待传送完成
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
@ -136,23 +130,23 @@ public class AutoTrackPathTask
|
|||||||
// 4. 针对点位进行直线追踪
|
// 4. 针对点位进行直线追踪
|
||||||
|
|
||||||
var trackCts = new CancellationTokenSource();
|
var trackCts = new CancellationTokenSource();
|
||||||
_cts.Token.Register(trackCts.Cancel);
|
_ct.Register(trackCts.Cancel);
|
||||||
var trackTask = Track(_way.WayPointList, angleOffset, trackCts);
|
var trackTask = Track(_way.WayPointList, angleOffset, trackCts);
|
||||||
trackTask.Start();
|
trackTask.Start();
|
||||||
var refreshStatusTask = RefreshStatus(trackCts);
|
var refreshStatusTask = RefreshStatus(trackCts.Token);
|
||||||
refreshStatusTask.Start();
|
refreshStatusTask.Start();
|
||||||
var jumpTask = Jump(trackCts);
|
var jumpTask = Jump(trackCts.Token);
|
||||||
jumpTask.Start();
|
jumpTask.Start();
|
||||||
await Task.WhenAll(trackTask, refreshStatusTask, jumpTask);
|
await Task.WhenAll(trackTask, refreshStatusTask, jumpTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MotionStatus _motionStatus = MotionStatus.Normal;
|
private MotionStatus _motionStatus = MotionStatus.Normal;
|
||||||
|
|
||||||
public Task Jump(CancellationTokenSource trackCts)
|
public Task Jump(CancellationToken trackCt)
|
||||||
{
|
{
|
||||||
return new Task(() =>
|
return new Task(() =>
|
||||||
{
|
{
|
||||||
while (!_cts.Token.IsCancellationRequested && !trackCts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested && !trackCt.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
if (_motionStatus == MotionStatus.Normal)
|
if (_motionStatus == MotionStatus.Normal)
|
||||||
{
|
{
|
||||||
@ -178,11 +172,11 @@ public class AutoTrackPathTask
|
|||||||
|
|
||||||
private double _targetAngle = 0;
|
private double _targetAngle = 0;
|
||||||
|
|
||||||
public Task RefreshStatus(CancellationTokenSource trackCts)
|
public Task RefreshStatus(CancellationToken trackCt)
|
||||||
{
|
{
|
||||||
return new Task(() =>
|
return new Task(() =>
|
||||||
{
|
{
|
||||||
while (!_cts.Token.IsCancellationRequested && !trackCts.Token.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested && !trackCt.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
using var ra = CaptureToRectArea();
|
using var ra = CaptureToRectArea();
|
||||||
_motionStatus = Bv.GetMotionStatus(ra);
|
_motionStatus = Bv.GetMotionStatus(ra);
|
||||||
@ -210,7 +204,7 @@ public class AutoTrackPathTask
|
|||||||
return new Task(() =>
|
return new Task(() =>
|
||||||
{
|
{
|
||||||
var currIndex = 0;
|
var currIndex = 0;
|
||||||
while (!_cts.IsCancellationRequested)
|
while (!_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var ra = CaptureToRectArea();
|
var ra = CaptureToRectArea();
|
||||||
var miniMapMat = GetMiniMapMat(ra) ?? throw new InvalidOperationException("当前不在主界面");
|
var miniMapMat = GetMiniMapMat(ra) ?? throw new InvalidOperationException("当前不在主界面");
|
||||||
|
@ -37,7 +37,7 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
|
|||||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
|
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
|
||||||
|
|
||||||
_recordTaskCts = new CancellationTokenSource();
|
_recordTaskCts = new CancellationTokenSource();
|
||||||
_recordTask = RecordTask(_recordTaskCts);
|
_recordTask = RecordTask(_recordTaskCts.Token);
|
||||||
_recordTask.Start();
|
_recordTask.Start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -58,17 +58,17 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task RecordTask(CancellationTokenSource cts)
|
public Task RecordTask(CancellationToken ct)
|
||||||
{
|
{
|
||||||
return new Task(() =>
|
return new Task(() =>
|
||||||
{
|
{
|
||||||
GiPath way = new();
|
GiPath way = new();
|
||||||
|
|
||||||
while (!cts.Token.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Sleep(10, cts);
|
Sleep(10, ct);
|
||||||
var ra = CaptureToRectArea();
|
var ra = CaptureToRectArea();
|
||||||
|
|
||||||
// 小地图匹配
|
// 小地图匹配
|
||||||
@ -76,7 +76,7 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
|
|||||||
var p = MatchTemplateHelper.MatchTemplate(ra.SrcGreyMat, tar, TemplateMatchModes.CCoeffNormed, null, 0.9);
|
var p = MatchTemplateHelper.MatchTemplate(ra.SrcGreyMat, tar, TemplateMatchModes.CCoeffNormed, null, 0.9);
|
||||||
if (p.X == 0 || p.Y == 0)
|
if (p.X == 0 || p.Y == 0)
|
||||||
{
|
{
|
||||||
Sleep(50, cts);
|
Sleep(50, ct);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Sleep(50, cts);
|
Sleep(50, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -100,6 +100,6 @@ public class PathPointRecorder : Singleton<PathPointRecorder>
|
|||||||
File.WriteAllText(Global.Absolute($@"log\way\{DateTime.Now:yyyy-MM-dd HH:mm:ss:ffff}.json"), JsonSerializer.Serialize(way, ConfigService.JsonOptions));
|
File.WriteAllText(Global.Absolute($@"log\way\{DateTime.Now:yyyy-MM-dd HH:mm:ss:ffff}.json"), JsonSerializer.Serialize(way, ConfigService.JsonOptions));
|
||||||
#endif
|
#endif
|
||||||
Logger.LogInformation("路线录制结束");
|
Logger.LogInformation("路线录制结束");
|
||||||
}, cts.Token);
|
}, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace BetterGenshinImpact.GameTask.AutoTrackPath;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 传送任务
|
/// 传送任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TpTask(CancellationTokenSource cts)
|
public class TpTask(CancellationToken ct)
|
||||||
{
|
{
|
||||||
private readonly QuickTeleportAssets _assets = QuickTeleportAssets.Instance;
|
private readonly QuickTeleportAssets _assets = QuickTeleportAssets.Instance;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
if (!Bv.IsInBigMapUi(ra1))
|
if (!Bv.IsInBigMapUi(ra1))
|
||||||
{
|
{
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_M);
|
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);
|
ra.ClickTo((int)clickX, (int)clickY);
|
||||||
|
|
||||||
// 触发一次快速传送功能
|
// 触发一次快速传送功能
|
||||||
await Delay(500, cts);
|
await Delay(500, ct);
|
||||||
await ClickTpPoint(CaptureToRectArea());
|
await ClickTpPoint(CaptureToRectArea());
|
||||||
|
|
||||||
// 等待传送完成
|
// 等待传送完成
|
||||||
for (var i = 0; i < 20; i++)
|
for (var i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
await Delay(1200, cts);
|
await Delay(1200, ct);
|
||||||
using var ra3 = CaptureToRectArea();
|
using var ra3 = CaptureToRectArea();
|
||||||
if (Bv.IsInMainUi(ra3))
|
if (Bv.IsInMainUi(ra3))
|
||||||
{
|
{
|
||||||
@ -161,7 +161,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
{
|
{
|
||||||
// 传送点未激活或不存在 按ESC回到大地图界面
|
// 传送点未激活或不存在 按ESC回到大地图界面
|
||||||
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);
|
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);
|
||||||
await Delay(300, cts);
|
await Delay(300, ct);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -231,14 +231,14 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
var moveUnit = dx > 0 ? 20 : -20;
|
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)));
|
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();
|
Simulation.SendInput.Mouse.LeftButtonDown();
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
for (var i = 0; i < dx / moveUnit; i++)
|
for (var i = 0; i < dx / moveUnit; i++)
|
||||||
{
|
{
|
||||||
Simulation.SendInput.Mouse.MoveMouseBy(moveUnit, 0).Sleep(60); // 60 保证没有惯性
|
Simulation.SendInput.Mouse.MoveMouseBy(moveUnit, 0).Sleep(60); // 60 保证没有惯性
|
||||||
}
|
}
|
||||||
|
|
||||||
Simulation.SendInput.Mouse.LeftButtonUp();
|
Simulation.SendInput.Mouse.LeftButtonUp();
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MouseMoveMapY(int dy)
|
public async Task MouseMoveMapY(int dy)
|
||||||
@ -246,7 +246,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
var moveUnit = dy > 0 ? 20 : -20;
|
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)));
|
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();
|
Simulation.SendInput.Mouse.LeftButtonDown();
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
// 原神地图在小范围内移动是无效的,所以先随便移动一下,所以肯定少移动一次
|
// 原神地图在小范围内移动是无效的,所以先随便移动一下,所以肯定少移动一次
|
||||||
for (var i = 0; i < dy / moveUnit; i++)
|
for (var i = 0; i < dy / moveUnit; i++)
|
||||||
{
|
{
|
||||||
@ -254,7 +254,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Simulation.SendInput.Mouse.LeftButtonUp();
|
Simulation.SendInput.Mouse.LeftButtonUp();
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point2f GetPositionFromBigMap()
|
public Point2f GetPositionFromBigMap()
|
||||||
@ -363,7 +363,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
if (Bv.BigMapIsUnderground(ra2))
|
if (Bv.BigMapIsUnderground(ra2))
|
||||||
{
|
{
|
||||||
ra2.Find(_assets.MapUndergroundToGroundButtonRo).Click();
|
ra2.Find(_assets.MapUndergroundToGroundButtonRo).Click();
|
||||||
await Delay(200, cts);
|
await Delay(200, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 识别当前位置
|
// 识别当前位置
|
||||||
@ -392,7 +392,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
if (minCountry != "当前位置")
|
if (minCountry != "当前位置")
|
||||||
{
|
{
|
||||||
GameCaptureRegion.GameRegionClick((rect, scale) => (rect.Width - 160 * scale, rect.Height - 60 * scale));
|
GameCaptureRegion.GameRegionClick((rect, scale) => (rect.Width - 160 * scale, rect.Height - 60 * scale));
|
||||||
await Delay(300, cts);
|
await Delay(300, ct);
|
||||||
var ra = CaptureToRectArea();
|
var ra = CaptureToRectArea();
|
||||||
var list = ra.FindMulti(new RecognitionObject
|
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();
|
list.FirstOrDefault(r => r.Text.Length == minCountry.Length && !r.Text.Contains("委托") && r.Text.Contains(minCountry))?.Click();
|
||||||
Logger.LogInformation("切换到区域:{Country}", minCountry);
|
Logger.LogInformation("切换到区域:{Country}", minCountry);
|
||||||
await Delay(500, cts);
|
await Delay(500, ct);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,7 +442,7 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
{
|
{
|
||||||
var time = TaskContext.Instance().Config.QuickTeleportConfig.WaitTeleportPanelDelay;
|
var time = TaskContext.Instance().Config.QuickTeleportConfig.WaitTeleportPanelDelay;
|
||||||
time = time < 300 ? 300 : time;
|
time = time < 300 ? 300 : time;
|
||||||
await Delay(time, cts);
|
await Delay(time, ct);
|
||||||
if (!CheckTeleportButton(CaptureToRectArea()))
|
if (!CheckTeleportButton(CaptureToRectArea()))
|
||||||
{
|
{
|
||||||
// 没传送确认图标说明点开的是未激活传送锚点
|
// 没传送确认图标说明点开的是未激活传送锚点
|
||||||
@ -514,4 +514,4 @@ public class TpTask(CancellationTokenSource cts)
|
|||||||
|
|
||||||
return hasMapChooseIcon;
|
return hasMapChooseIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using BetterGenshinImpact.Core.Recognition.OCR;
|
using BetterGenshinImpact.Core.Recognition.OCR;
|
||||||
using BetterGenshinImpact.Core.Script;
|
|
||||||
using BetterGenshinImpact.Core.Simulator;
|
using BetterGenshinImpact.Core.Simulator;
|
||||||
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
|
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
|
||||||
using BetterGenshinImpact.GameTask.AutoWood.Assets;
|
using BetterGenshinImpact.GameTask.AutoWood.Assets;
|
||||||
@ -8,7 +7,6 @@ using BetterGenshinImpact.GameTask.Common;
|
|||||||
using BetterGenshinImpact.GameTask.Model.Area;
|
using BetterGenshinImpact.GameTask.Model.Area;
|
||||||
using BetterGenshinImpact.Genshin.Settings;
|
using BetterGenshinImpact.Genshin.Settings;
|
||||||
using BetterGenshinImpact.View.Drawable;
|
using BetterGenshinImpact.View.Drawable;
|
||||||
using BetterGenshinImpact.ViewModel.Pages;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
@ -42,7 +40,7 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
|
|
||||||
private readonly WoodTaskParam _taskParam;
|
private readonly WoodTaskParam _taskParam;
|
||||||
|
|
||||||
private CancellationTokenSource? _cts;
|
private CancellationToken _ct;
|
||||||
|
|
||||||
public AutoWoodTask(WoodTaskParam taskParam)
|
public AutoWoodTask(WoodTaskParam taskParam)
|
||||||
{
|
{
|
||||||
@ -53,11 +51,11 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
_printer = new WoodStatisticsPrinter(_assets);
|
_printer = new WoodStatisticsPrinter(_assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Start(CancellationTokenSource cts)
|
public Task Start(CancellationToken ct)
|
||||||
{
|
{
|
||||||
var runTimeWatch = new Stopwatch();
|
var runTimeWatch = new Stopwatch();
|
||||||
_cts = cts;
|
_ct = ct;
|
||||||
_printer.Cts = _cts;
|
_printer.Ct = _ct;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -106,14 +104,14 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogInformation("第{Cnt}次伐木", i + 1);
|
Logger.LogInformation("第{Cnt}次伐木", i + 1);
|
||||||
if (_cts.IsCancellationRequested)
|
if (_ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Felling(_taskParam, i + 1 == _taskParam.WoodRoundNum);
|
Felling(_taskParam, i + 1 == _taskParam.WoodRoundNum);
|
||||||
VisionContext.Instance().DrawContent.ClearAll();
|
VisionContext.Instance().DrawContent.ClearAll();
|
||||||
Sleep(500, _cts);
|
Sleep(500, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
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+)")]
|
[GeneratedRegex("([^\\d\\n]+)[×x](\\d+)")]
|
||||||
private static partial Regex _parseWoodStatisticsRegex();
|
private static partial Regex _parseWoodStatisticsRegex();
|
||||||
@ -217,7 +215,7 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
|
|
||||||
private void SleepDurationBetweenOcrs(WoodTaskParam taskParam)
|
private void SleepDurationBetweenOcrs(WoodTaskParam taskParam)
|
||||||
{
|
{
|
||||||
Sleep(_firstWoodOcr ? 300 : 100, Cts);
|
Sleep(_firstWoodOcr ? 300 : 100, Ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string WoodTextAreaOcr()
|
private string WoodTextAreaOcr()
|
||||||
@ -433,7 +431,7 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
{
|
{
|
||||||
NewRetry.Do(() =>
|
NewRetry.Do(() =>
|
||||||
{
|
{
|
||||||
Sleep(1, _cts);
|
Sleep(1, _ct);
|
||||||
using var contentRegion = CaptureToRectArea();
|
using var contentRegion = CaptureToRectArea();
|
||||||
using var ra = contentRegion.Find(_assets.TheBoonOfTheElderTreeRo);
|
using var ra = contentRegion.Find(_assets.TheBoonOfTheElderTreeRo);
|
||||||
if (ra.IsEmpty())
|
if (ra.IsEmpty())
|
||||||
@ -447,12 +445,12 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
|
|
||||||
Simulation.SendInput.Keyboard.KeyPress(_zKey);
|
Simulation.SendInput.Keyboard.KeyPress(_zKey);
|
||||||
Debug.WriteLine("[AutoWood] Z");
|
Debug.WriteLine("[AutoWood] Z");
|
||||||
Sleep(500, _cts);
|
Sleep(500, _ct);
|
||||||
}, TimeSpan.FromSeconds(1), 120);
|
}, TimeSpan.FromSeconds(1), 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(300, _cts);
|
Sleep(300, _ct);
|
||||||
Sleep(TaskContext.Instance().Config.AutoWoodConfig.AfterZSleepDelay, _cts);
|
Sleep(TaskContext.Instance().Config.AutoWoodConfig.AfterZSleepDelay, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PressEsc(WoodTaskParam taskParam)
|
private void PressEsc(WoodTaskParam taskParam)
|
||||||
@ -465,13 +463,13 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
// Simulation.SendInput.Keyboard.KeyPress(VK.VK_ESCAPE);
|
// Simulation.SendInput.Keyboard.KeyPress(VK.VK_ESCAPE);
|
||||||
// }
|
// }
|
||||||
Debug.WriteLine("[AutoWood] Esc");
|
Debug.WriteLine("[AutoWood] Esc");
|
||||||
Sleep(800, _cts);
|
Sleep(800, _ct);
|
||||||
// 确认在菜单界面
|
// 确认在菜单界面
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
NewRetry.Do(() =>
|
NewRetry.Do(() =>
|
||||||
{
|
{
|
||||||
Sleep(1, _cts);
|
Sleep(1, _ct);
|
||||||
using var contentRegion = CaptureToRectArea();
|
using var contentRegion = CaptureToRectArea();
|
||||||
using var ra = contentRegion.Find(_assets.MenuBagRo);
|
using var ra = contentRegion.Find(_assets.MenuBagRo);
|
||||||
if (ra.IsEmpty())
|
if (ra.IsEmpty())
|
||||||
@ -492,7 +490,7 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
|
|
||||||
Debug.WriteLine("[AutoWood] Click exit button");
|
Debug.WriteLine("[AutoWood] Click exit button");
|
||||||
|
|
||||||
Sleep(500, _cts);
|
Sleep(500, _ct);
|
||||||
|
|
||||||
// 点击确认
|
// 点击确认
|
||||||
using var contentRegion = CaptureToRectArea();
|
using var contentRegion = CaptureToRectArea();
|
||||||
@ -508,14 +506,14 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
{
|
{
|
||||||
if (_login3rdParty.IsAvailabled)
|
if (_login3rdParty.IsAvailabled)
|
||||||
{
|
{
|
||||||
Sleep(1, _cts);
|
Sleep(1, _ct);
|
||||||
_login3rdParty.Login(_cts);
|
_login3rdParty.Login(_ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
var clickCnt = 0;
|
var clickCnt = 0;
|
||||||
for (var i = 0; i < 50; i++)
|
for (var i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
Sleep(1, _cts);
|
Sleep(1, _ct);
|
||||||
|
|
||||||
using var contentRegion = CaptureToRectArea();
|
using var contentRegion = CaptureToRectArea();
|
||||||
using var ra = contentRegion.Find(_assets.EnterGameRo);
|
using var ra = contentRegion.Find(_assets.EnterGameRo);
|
||||||
@ -529,12 +527,12 @@ public partial class AutoWoodTask : ISoloTask
|
|||||||
{
|
{
|
||||||
if (clickCnt > 2)
|
if (clickCnt > 2)
|
||||||
{
|
{
|
||||||
Sleep(5000, _cts);
|
Sleep(5000, _ct);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(1000, _cts);
|
Sleep(1000, _ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickCnt == 0)
|
if (clickCnt == 0)
|
||||||
|
@ -76,11 +76,11 @@ internal sealed class Login3rdParty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Login(CancellationTokenSource cts)
|
public void Login(CancellationToken ct)
|
||||||
{
|
{
|
||||||
int failCount = default;
|
int failCount = default;
|
||||||
|
|
||||||
while (!LoginPrivate(cts))
|
while (!LoginPrivate(ct))
|
||||||
{
|
{
|
||||||
// It is necessary to support exitable trying.
|
// It is necessary to support exitable trying.
|
||||||
// Can exit trying when over than 10s.
|
// Can exit trying when over than 10s.
|
||||||
@ -90,12 +90,12 @@ internal sealed class Login3rdParty
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Debug.WriteLine($"[AutoWood] Fail to check login button {failCount} time(s).");
|
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.");
|
Debug.WriteLine("[AutoWood] Exit while check login button.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoginPrivate(CancellationTokenSource cts)
|
private bool LoginPrivate(CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (Type == The3rdPartyType.Bilibili)
|
if (Type == The3rdPartyType.Bilibili)
|
||||||
{
|
{
|
||||||
@ -104,7 +104,7 @@ internal sealed class Login3rdParty
|
|||||||
if (GetBHWnd(process) != IntPtr.Zero)
|
if (GetBHWnd(process) != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
// Just for login WebUI fadein chattering
|
// Just for login WebUI fadein chattering
|
||||||
Sleep(4000, cts);
|
Sleep(4000, ct);
|
||||||
|
|
||||||
var p = TaskContext.Instance()
|
var p = TaskContext.Instance()
|
||||||
.SystemInfo.CaptureAreaRect.GetCenterPoint()
|
.SystemInfo.CaptureAreaRect.GetCenterPoint()
|
||||||
@ -114,7 +114,7 @@ internal sealed class Login3rdParty
|
|||||||
Debug.WriteLine("[AutoWood] Click login button for the B one");
|
Debug.WriteLine("[AutoWood] Click login button for the B one");
|
||||||
|
|
||||||
// Just for login WebUI fadeout chattering
|
// Just for login WebUI fadeout chattering
|
||||||
Sleep(3000, cts);
|
Sleep(3000, ct);
|
||||||
|
|
||||||
if (GetBHWnd(process) != IntPtr.Zero)
|
if (GetBHWnd(process) != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
@ -39,9 +39,73 @@ public class TaskControl
|
|||||||
Thread.Sleep(millisecondsTimeout);
|
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("取消自动任务");
|
throw new NormalEndException("取消自动任务");
|
||||||
}
|
}
|
||||||
@ -53,7 +117,7 @@ public class TaskControl
|
|||||||
|
|
||||||
NewRetry.Do(() =>
|
NewRetry.Do(() =>
|
||||||
{
|
{
|
||||||
if (cts is { IsCancellationRequested: true })
|
if (ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
throw new NormalEndException("取消自动任务");
|
throw new NormalEndException("取消自动任务");
|
||||||
}
|
}
|
||||||
@ -65,15 +129,15 @@ public class TaskControl
|
|||||||
}
|
}
|
||||||
}, TimeSpan.FromSeconds(1), 100);
|
}, TimeSpan.FromSeconds(1), 100);
|
||||||
Thread.Sleep(millisecondsTimeout);
|
Thread.Sleep(millisecondsTimeout);
|
||||||
if (cts is { IsCancellationRequested: true })
|
if (ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
throw new NormalEndException("取消自动任务");
|
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("取消自动任务");
|
throw new NormalEndException("取消自动任务");
|
||||||
}
|
}
|
||||||
@ -85,7 +149,7 @@ public class TaskControl
|
|||||||
|
|
||||||
NewRetry.Do(() =>
|
NewRetry.Do(() =>
|
||||||
{
|
{
|
||||||
if (cts is { IsCancellationRequested: true })
|
if (ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
throw new NormalEndException("取消自动任务");
|
throw new NormalEndException("取消自动任务");
|
||||||
}
|
}
|
||||||
@ -96,8 +160,8 @@ public class TaskControl
|
|||||||
throw new RetryException("当前获取焦点的窗口不是原神");
|
throw new RetryException("当前获取焦点的窗口不是原神");
|
||||||
}
|
}
|
||||||
}, TimeSpan.FromSeconds(1), 100);
|
}, TimeSpan.FromSeconds(1), 100);
|
||||||
await Task.Delay(millisecondsTimeout, cts.Token);
|
await Task.Delay(millisecondsTimeout, ct);
|
||||||
if (cts is { IsCancellationRequested: true })
|
if (ct is { IsCancellationRequested: true })
|
||||||
{
|
{
|
||||||
throw new NormalEndException("取消自动任务");
|
throw new NormalEndException("取消自动任务");
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,5 @@ namespace BetterGenshinImpact.GameTask;
|
|||||||
|
|
||||||
public interface ISoloTask
|
public interface ISoloTask
|
||||||
{
|
{
|
||||||
Task Start(CancellationTokenSource cts);
|
Task Start(CancellationToken ct);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -102,7 +102,7 @@ public class TaskRunner
|
|||||||
|
|
||||||
public async Task RunSoloTaskAsync(ISoloTask soloTask)
|
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()
|
public void Init()
|
||||||
|
@ -465,7 +465,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
|||||||
Config.HotKeyConfig.RecBigMapPosHotkeyType,
|
Config.HotKeyConfig.RecBigMapPosHotkeyType,
|
||||||
(_, _) =>
|
(_, _) =>
|
||||||
{
|
{
|
||||||
var p = new TpTask(new CancellationTokenSource()).GetPositionFromBigMap();
|
var p = new TpTask(new CancellationToken()).GetPositionFromBigMap();
|
||||||
_logger.LogInformation("大地图位置:{Position}", p);
|
_logger.LogInformation("大地图位置:{Position}", p);
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
@ -561,7 +561,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
|||||||
(_, _) =>
|
(_, _) =>
|
||||||
{
|
{
|
||||||
NahidaCollectHandler handler = new NahidaCollectHandler();
|
NahidaCollectHandler handler = new NahidaCollectHandler();
|
||||||
handler.RunAsync(new CancellationTokenSource());
|
handler.RunAsync(new CancellationToken());
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
debugDirectory.Children.Add(new HotKeySettingModel(
|
debugDirectory.Children.Add(new HotKeySettingModel(
|
||||||
|
Loading…
Reference in New Issue
Block a user