Files
better-genshin-impact/BetterGenshinImpact/GameTask/TaskRunner.cs
辉鸭蛋 a06f0fcdb2 auto pathing: fix not releasing the mouse and keyboard when stopping tasks
更新日志和黑名单

移除 `PathExecutor.cs` 中的无用引用,重构 `Pathing` 方法,添加 `InitializePathing` 和 `ConvertWaypoints` 方法,提取传送点处理逻辑到 `HandleTeleportWaypoint` 方法。修改 `TpTask.cs` 中的日志格式为浮点数格式。将 `TaskRunner.cs` 中的 `FireAndForgetAsync` 方法重命名为 `RunThreadAsync`,并在 `ScriptService.cs` 中相应替换调用。为 `DpiHelper.cs` 中的 `ScaleY` 属性添加注释。更新 `pick_black_lists.json`,添加新的黑名单项 `"摆放巧像"`。在 `MapPathingViewModel.cs` 中添加 `_mapViewer` 字段,并在 `OnOpenMapViewer` 方法中使用。
2024-09-09 21:57:48 +08:00

172 lines
5.7 KiB
C#

using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
using BetterGenshinImpact.GameTask.Model.Enum;
using BetterGenshinImpact.View;
using BetterGenshinImpact.View.Drawable;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.Helpers;
using Wpf.Ui.Violeta.Controls;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask;
/// <summary>
/// 用于以独立任务的方式执行任意方法
/// </summary>
public class TaskRunner
{
private readonly ILogger<TaskRunner> _logger = App.GetLogger<TaskRunner>();
private readonly DispatcherTimerOperationEnum _timerOperation = DispatcherTimerOperationEnum.None;
private readonly string _name = string.Empty;
public TaskRunner()
{
}
public TaskRunner(DispatcherTimerOperationEnum timerOperation)
{
_timerOperation = timerOperation;
}
/// <summary>
/// 加锁并独立运行任务
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public async Task RunAsync(Func<Task> action)
{
// 加锁
var hasLock = await TaskSemaphore.WaitAsync(0);
if (!hasLock)
{
_logger.LogError("任务启动失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
return;
}
try
{
_logger.LogInformation("→ {Text}", _name + "任务启动!");
// 初始化
Init();
// 发送运行任务通知
SendNotification();
CancellationContext.Instance.Set();
await action();
}
catch (NormalEndException e)
{
_logger.LogInformation("任务中断:{Msg}", e.Message);
SendNotification();
}
catch (Exception e)
{
_logger.LogError(e.Message);
_logger.LogDebug(e.StackTrace);
SendNotification();
}
finally
{
End();
_logger.LogInformation("→ {Text}", _name + "任务结束");
SendNotification();
CancellationContext.Instance.Clear();
// 释放锁
if (hasLock)
{
TaskSemaphore.Release();
}
}
}
public void FireAndForget(Func<Task> action)
{
Task.Run(() => RunAsync(action));
}
public async Task RunThreadAsync(Func<Task> action)
{
await Task.Run(() => RunAsync(action));
}
public void Init()
{
if (!TaskContext.Instance().IsInitialized)
{
UIDispatcherHelper.Invoke(() => { Toast.Warning("请先在启动页,启动截图器再使用本功能"); });
throw new NormalEndException("请先在启动页,启动截图器再使用本功能");
}
// 激活原神窗口
var maskWindow = MaskWindow.Instance();
SystemControl.ActivateWindow();
maskWindow.Invoke(maskWindow.Show);
if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
{
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待日志窗口被激活
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Stop);
}
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImage)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
}
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTrigger)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
}
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
TaskTriggerDispatcher.Instance().ClearTriggers();
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
}
}
public void End()
{
if (!TaskContext.Instance().IsInitialized)
{
return;
}
VisionContext.Instance().DrawContent.ClearAll();
if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Start);
}
else if (_timerOperation is DispatcherTimerOperationEnum.UseCacheImage or DispatcherTimerOperationEnum.UseCacheImageWithTrigger or DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
{
// 还原到原来的模式
if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled || TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
}
else
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.NormalTrigger);
}
if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
{
TaskTriggerDispatcher.Instance().SetTriggers(GameTaskManager.LoadInitialTriggers());
}
}
}
public void SendNotification()
{
}
}