Files
better-genshin-impact/BetterGenshinImpact/GameTask/GameTaskManager.cs
辉鸭蛋 c37c43ce92 dispatcher supprot pathing script
调度器支持路径追踪功能及多项代码优化

在 `ScriptGroupProject.cs` 中:
- 添加对多个命名空间的引用。
- 修改构造函数,增加 `folder` 和 `type` 参数,删除 `kmName` 参数。
- 添加 `BuildKeyMouseProject` 和 `BuildPathingProject` 静态方法。
- 在 `Run` 方法中增加 `Pathing` 类型处理逻辑。
- 在 `ScriptGroupProjectExtensions` 中增加 `Pathing` 类型描述。

在 `PathingTask.cs` 中:
- 添加 `FileName` 属性,并在 `BuildFromFilePath` 方法中设置。

在 `Navigation.cs` 中:
- 将 `Navigation` 类改为 `public`。
- 添加 `_isWarmUp` 静态字段,防止重复加载地图特征点。
- 将 `GetPosition`、`GetTargetOrientation` 和 `GetDistance` 方法改为 `public`。

在 `GameTaskManager.cs` 中:
- 在 `AddTrigger` 方法中添加注释,指出清理 `TriggerDictionary` 的问题。

在 `ScriptService.cs` 中:
- 在 `RunMulti` 方法中增加 `hasTimer` 变量,并在处理 `Pathing` 类型时设置。
- 修改 `RunMulti` 方法逻辑,确保无定时操作时检查 JS 脚本。
- 在 `Run` 方法中增加 `Pathing` 类型处理逻辑。

在 `MapPathingPage.xaml` 中:
- 注释掉第四列定义和相关 `Grid` 元素。
- 修改 `ListView` 中 `GridViewColumn` 的 `DisplayMemberBinding`。

在 `ScriptControlPage.xaml` 中:
- 在 `ContextMenu` 中添加新的 `MenuItem`,用于添加路径追踪任务。

在 `PromptDialog.xaml.cs` 中:
- 添加新的 `Prompt` 方法,允许指定对话框大小。
- 修改 `ResponseText` 属性逻辑,增加默认返回值。

在 `MapPathingViewModel.cs` 中:
- 调整 `using` 语句顺序,删除重复引用。

在 `ScriptControlViewModel.cs` 中:
- 修改 `OnAddKmScript` 方法,使用 `BuildKeyMouseProject` 方法创建键鼠脚本项目。
- 添加 `OnAddPathing` 方法及其辅助方法,用于添加路径追踪任务。
- 在 `RunSelectedScriptGroup` 方法中,将脚本运行逻辑放入 `Task.Run` 中,避免阻塞 UI 线程。
2024-09-08 23:17:48 +08:00

168 lines
6.1 KiB
C#

using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Recognition.OpenCv;
using BetterGenshinImpact.Core.Script.Dependence.Model.TimerConfig;
using BetterGenshinImpact.GameTask.AutoFight.Assets;
using BetterGenshinImpact.GameTask.AutoFishing.Assets;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Assets;
using BetterGenshinImpact.GameTask.AutoPick.Assets;
using BetterGenshinImpact.GameTask.AutoSkip.Assets;
using BetterGenshinImpact.GameTask.AutoWood.Assets;
using BetterGenshinImpact.GameTask.Common.Element.Assets;
using BetterGenshinImpact.GameTask.GameLoading;
using BetterGenshinImpact.GameTask.GameLoading.Assets;
using BetterGenshinImpact.GameTask.Placeholder;
using BetterGenshinImpact.GameTask.QuickSereniteaPot.Assets;
using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
using BetterGenshinImpact.View.Drawable;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using OpenCvSharp;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace BetterGenshinImpact.GameTask;
internal class GameTaskManager
{
public static ConcurrentDictionary<string, ITaskTrigger>? TriggerDictionary { get; set; }
/// <summary>
/// 一定要在任务上下文初始化完毕后使用
/// </summary>
/// <returns></returns>
public static List<ITaskTrigger> LoadInitialTriggers()
{
ReloadAssets();
TriggerDictionary = new ConcurrentDictionary<string, ITaskTrigger>();
TriggerDictionary.TryAdd("RecognitionTest", new TestTrigger());
TriggerDictionary.TryAdd("GameLoading", new GameLoadingTrigger());
TriggerDictionary.TryAdd("AutoPick", new AutoPick.AutoPickTrigger());
TriggerDictionary.TryAdd("QuickTeleport", new QuickTeleport.QuickTeleportTrigger());
TriggerDictionary.TryAdd("AutoSkip", new AutoSkip.AutoSkipTrigger());
TriggerDictionary.TryAdd("AutoFish", new AutoFishing.AutoFishingTrigger());
TriggerDictionary.TryAdd("AutoCook", new AutoCook.AutoCookTrigger());
return ConvertToTriggerList();
}
public static List<ITaskTrigger> ConvertToTriggerList(bool allEnabled = false)
{
if (TriggerDictionary is null)
{
return [];
}
var loadedTriggers = TriggerDictionary.Values.ToList();
loadedTriggers.ForEach(i => i.Init());
if (allEnabled)
{
loadedTriggers.ForEach(i => i.IsEnabled = true);
}
loadedTriggers = [.. loadedTriggers.OrderByDescending(i => i.Priority)];
return loadedTriggers;
}
public static void ClearTriggers()
{
TriggerDictionary?.Clear();
}
/// <summary>
/// 通过名称添加触发器
/// </summary>
/// <param name="name"></param>
/// <param name="externalConfig"></param>
public static void AddTrigger(string name, object? externalConfig)
{
TriggerDictionary ??= new ConcurrentDictionary<string, ITaskTrigger>();
TriggerDictionary.Clear(); //TODO 有问题,不应该清理
if (name == "AutoPick")
{
TriggerDictionary.TryAdd("AutoPick", new AutoPick.AutoPickTrigger(externalConfig as AutoPickExternalConfig));
}
// else if (name == "AutoSkip")
// {
// TriggerDictionary.Add("AutoSkip", new AutoSkip.AutoSkipTrigger());
// }
// else if (name == "AutoFish")
// {
// TriggerDictionary.Add("AutoFish", new AutoFishing.AutoFishingTrigger());
// }
}
public static void RefreshTriggerConfigs()
{
if (TriggerDictionary is { Count: > 0 })
{
TriggerDictionary.GetValueOrDefault("AutoPick")?.Init();
TriggerDictionary.GetValueOrDefault("AutoSkip")?.Init();
TriggerDictionary.GetValueOrDefault("AutoFish")?.Init();
TriggerDictionary.GetValueOrDefault("QuickTeleport")?.Init();
TriggerDictionary.GetValueOrDefault("GameLoading")?.Init();
TriggerDictionary.GetValueOrDefault("AutoCook")?.Init();
// 清理画布
WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<object>(new object(), "RemoveAllButton", new object(), ""));
VisionContext.Instance().DrawContent.ClearAll();
}
ReloadAssets();
}
public static void ReloadAssets()
{
AutoPickAssets.DestroyInstance();
AutoSkipAssets.DestroyInstance();
AutoFishingAssets.DestroyInstance();
QuickTeleportAssets.DestroyInstance();
AutoWoodAssets.DestroyInstance();
AutoGeniusInvokationAssets.DestroyInstance();
AutoFightAssets.DestroyInstance();
ElementAssets.DestroyInstance();
QuickSereniteaPotAssets.DestroyInstance();
GameLoadingAssets.DestroyInstance();
}
/// <summary>
/// 获取素材图片并缩放
/// todo 支持多语言
/// </summary>
/// <param name="featName">任务名称</param>
/// <param name="assertName">素材文件名</param>
/// <param name="flags"></param>
/// <returns></returns>
/// <exception cref="FileNotFoundException"></exception>
public static Mat LoadAssetImage(string featName, string assertName, ImreadModes flags = ImreadModes.Color)
{
var info = TaskContext.Instance().SystemInfo;
var assetsFolder = Global.Absolute($@"GameTask\{featName}\Assets\{info.GameScreenSize.Width}x{info.GameScreenSize.Height}");
if (!Directory.Exists(assetsFolder))
{
assetsFolder = Global.Absolute($@"GameTask\{featName}\Assets\1920x1080");
}
if (!Directory.Exists(assetsFolder))
{
throw new FileNotFoundException($"未找到{featName}的素材文件夹");
}
var filePath = Path.Combine(assetsFolder, assertName);
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"未找到{featName}中的{assertName}文件");
}
var mat = Mat.FromStream(File.OpenRead(filePath), flags);
if (info.GameScreenSize.Width != 1920)
{
mat = ResizeHelper.Resize(mat, info.AssetScale);
}
return mat;
}
}