Files
better-genshin-impact/BetterGenshinImpact/GameTask/AutoMusicGame/AutoMusicGameTask.cs
辉鸭蛋 5a0f7226ed update ISoloTask
更新 Start 方法以接受 CancellationTokenSource 参数

这些更改主要是为了使 `Start` 方法能够接受 `CancellationTokenSource` 参数,从而更好地控制任务的取消操作。通过传递 `CancellationTokenSource`,可以在需要时取消正在运行的任务,提高了代码的灵活性和可控性。

具体更改包括:
- 将 `Start` 方法的签名从无参数更改为接受 `CancellationTokenSource` 参数。
- 在多个任务类(如 `AutoDomainTask.cs`、`AutoFightTask.cs`、`AutoGeniusInvokationTask.cs`、`AutoMusicGameTask.cs`、`AutoWoodTask.cs`)中,更新 `Start` 方法以接受并使用传入的 `CancellationTokenSource`。
- 在 `Duel.cs` 中,更新 `RunAsync` 和 `Run` 方法的参数以接受 `CancellationTokenSource`,并将 `Cts` 赋值为传入的 `cts`。
- 在 `ISoloTask.cs` 接口中,更新 `Start` 方法的签名以接受 `CancellationTokenSource` 参数。
- 在 `TaskRunner.cs` 中,调用 `soloTask.Start` 时传入 `CancellationContext.Instance.Cts` 作为参数。
2024-09-23 00:04:09 +08:00

110 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.Core.Simulator;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Vanara.PInvoke;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask.AutoMusicGame;
public class AutoMusicGameTask(AutoMusicGameParam taskParam) : ISoloTask
{
private readonly ConcurrentDictionary<User32.VK, int> _keyX = new()
{
[User32.VK.VK_A] = 417,
[User32.VK.VK_S] = 632,
[User32.VK.VK_D] = 846,
[User32.VK.VK_J] = 1065,
[User32.VK.VK_K] = 1282,
[User32.VK.VK_L] = 1500
};
private readonly int _keyY = 916;
private readonly IntPtr _hWnd = TaskContext.Instance().GameHandle;
public Task Start(CancellationTokenSource cts)
{
Init();
var assetScale = TaskContext.Instance().SystemInfo.AssetScale;
var taskFactory = new TaskFactory();
var taskList = new List<Task>();
// 计算按键位置
var gameCaptureRegion = CaptureToRectArea();
foreach (var keyValuePair in _keyX)
{
var (x, y) = gameCaptureRegion.ConvertPositionToGameCaptureRegion((int)(keyValuePair.Value * assetScale), (int)(_keyY * assetScale));
// 添加任务
taskList.Add(taskFactory.StartNew(() => DoWhitePressWin32(cts, keyValuePair.Key, new Point(x, y))));
}
Task.WaitAll([.. taskList]);
return Task.CompletedTask;
}
private void DoWhitePressWin32(CancellationTokenSource cts, User32.VK key, Point point)
{
while (!cts.Token.IsCancellationRequested)
{
Thread.Sleep(10);
// Stopwatch sw = new();
// sw.Start();
var hdc = User32.GetDC(_hWnd);
var c = Gdi32.GetPixel(hdc, point.X, point.Y);
Gdi32.DeleteDC(hdc);
if (c.B < 220)
{
KeyDown(key);
while (!cts.Token.IsCancellationRequested)
{
Thread.Sleep(10);
hdc = User32.GetDC(_hWnd);
c = Gdi32.GetPixel(hdc, point.X, point.Y);
Gdi32.DeleteDC(hdc);
if (c.B >= 220)
{
break;
}
}
KeyUp(key);
}
// sw.Stop();
// Debug.WriteLine($"GetPixel 耗时:{sw.ElapsedMilliseconds} {point.X},{point.Y})颜色{c.R},{c.G},{c.B}");
}
}
private void KeyUp(User32.VK key)
{
Simulation.SendInput.Keyboard.KeyUp(key);
}
private void KeyDown(User32.VK key)
{
Simulation.SendInput.Keyboard.KeyDown(key);
}
private void Init()
{
LogScreenResolution();
}
private void LogScreenResolution()
{
var gameScreenSize = SystemControl.GetGameScreenRect(TaskContext.Instance().GameHandle);
if (gameScreenSize.Width * 9 != gameScreenSize.Height * 16)
{
Logger.LogWarning("游戏窗口分辨率不是 16:9 !当前分辨率为 {Width}x{Height} , 非 16:9 分辨率的游戏可能无法正常使用自动活动音游功能 !", gameScreenSize.Width, gameScreenSize.Height);
}
}
}