From 4e6190ac7b2e1414e92a787171fa1e03ede270f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 9 Sep 2024 22:42:35 +0800 Subject: [PATCH] fixed #598 --- .../GameTask/AutoPathing/Model/PathingTask.cs | 7 + .../GameTask/TaskTriggerDispatcher.cs | 5 + .../Service/Interface/IScriptService.cs | 4 +- BetterGenshinImpact/Service/ScriptService.cs | 233 +++++++++--------- .../ViewModel/Pages/JsListViewModel.cs | 2 +- .../ViewModel/Pages/MapPathingViewModel.cs | 22 +- 6 files changed, 151 insertions(+), 122 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/Model/PathingTask.cs b/BetterGenshinImpact/GameTask/AutoPathing/Model/PathingTask.cs index be965284..d1c14187 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/Model/PathingTask.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/Model/PathingTask.cs @@ -16,6 +16,12 @@ public class PathingTask [JsonIgnore] public string FileName { get; set; } = string.Empty; + /// + /// 实际存储的文件路径 + /// + [JsonIgnore] + public string FullPath { get; set; } = string.Empty; + public PathingTaskInfo Info { get; set; } = new(); public List Positions { get; set; } = []; @@ -24,6 +30,7 @@ public class PathingTask var json = File.ReadAllText(filePath); var task = JsonSerializer.Deserialize(json, PathRecorder.JsonOptions) ?? throw new Exception("Failed to deserialize PathingTask"); task.FileName = Path.GetFileName(filePath); + task.FullPath = filePath; return task; } diff --git a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs index e31ff813..eb67a351 100644 --- a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs +++ b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs @@ -186,6 +186,11 @@ namespace BetterGenshinImpact.GameTask } } + public System.Timers.Timer GetTimer() + { + return _timer; + } + /// /// 启动独立任务 /// diff --git a/BetterGenshinImpact/Service/Interface/IScriptService.cs b/BetterGenshinImpact/Service/Interface/IScriptService.cs index 3cd8fa17..6065eb1a 100644 --- a/BetterGenshinImpact/Service/Interface/IScriptService.cs +++ b/BetterGenshinImpact/Service/Interface/IScriptService.cs @@ -6,7 +6,7 @@ namespace BetterGenshinImpact.Service.Interface; public interface IScriptService { - Task RunMulti(List folderNameList, string? groupName = null); + Task RunMultiJs(List folderNameList, string? groupName = null); - Task RunMulti(IEnumerable projectList, string groupName); + Task RunMulti(IEnumerable projectList, string? groupName = null); } diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index e05df48d..04772bdf 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -1,4 +1,6 @@ -using BetterGenshinImpact.Core.Script.Project; +using BetterGenshinImpact.Core.Script; +using BetterGenshinImpact.Core.Script.Group; +using BetterGenshinImpact.Core.Script.Project; using BetterGenshinImpact.GameTask; using BetterGenshinImpact.GameTask.Model.Enum; using BetterGenshinImpact.Service.Interface; @@ -9,10 +11,6 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Windows.Documents; -using BetterGenshinImpact.Core.Script.Group; -using BetterGenshinImpact.Core.Script; -using BetterGenshinImpact.Helpers; namespace BetterGenshinImpact.Service; @@ -20,7 +18,7 @@ public partial class ScriptService(HomePageViewModel homePageViewModel) : IScrip { private readonly ILogger _logger = App.GetLogger(); - public async Task RunMulti(List folderNameList, string? groupName = null) + public async Task RunMultiJs(List folderNameList, string? groupName = null) { // 重新加载脚本项目 var projects = folderNameList.Select(name => new ScriptProject(name)).ToList(); @@ -79,52 +77,13 @@ public partial class ScriptService(HomePageViewModel homePageViewModel) : IScrip } } - public async Task RunMulti(IEnumerable projectList, string groupName) + public async Task RunMulti(IEnumerable projectList, string? groupName = null) { var hasTimer = false; + var list = ReloadScriptProjects(projectList, ref hasTimer); - // 重新加载脚本项目 并放入一个新的列表 - var list = new List(); - foreach (var project in projectList) - { - if (project.Type == "Javascript") - { - var newProject = new ScriptGroupProject(new ScriptProject(project.FolderName)); ; - newProject.Status = project.Status; - newProject.Schedule = project.Schedule; - newProject.RunNum = project.RunNum; - newProject.JsScriptSettingsObject = project.JsScriptSettingsObject; - list.Add(newProject); - } - else if (project.Type == "KeyMouse") - { - var newProject = ScriptGroupProject.BuildKeyMouseProject(project.FolderName); - newProject.Status = project.Status; - newProject.Schedule = project.Schedule; - newProject.RunNum = project.RunNum; - list.Add(newProject); - } - else if (project.Type == "Pathing") - { - var newProject = ScriptGroupProject.BuildPathingProject(project.Name, project.FolderName); - newProject.Status = project.Status; - newProject.Schedule = project.Schedule; - newProject.RunNum = project.RunNum; - list.Add(newProject); - hasTimer = true; // 路径追踪任务一定有实时任务操作 - } - } - - // 判断其中的 - List jsProjects = []; - foreach (var project in list) - { - if (project is { Type: "Javascript", Project: not null }) - { - jsProjects.Add(project.Project); - } - } - + // 针对JS 脚本,检查是否包含定时器操作 + var jsProjects = ExtractJsProjects(list); if (!hasTimer && jsProjects.Count > 0) { var codeList = await ReadCodeList(jsProjects); @@ -136,81 +95,133 @@ public partial class ScriptService(HomePageViewModel homePageViewModel) : IScrip if (hasTimer) { - _logger.LogInformation("配置组 {Name} 包含实时任务操作调用", groupName); + _logger.LogInformation("配置组 {Name} 包含实时任务操作调用", groupName ?? "默认"); } + _logger.LogInformation("配置组 {Name} 加载完成,共{Cnt}个脚本,开始执行", groupName ?? "默认", list.Count); - _logger.LogInformation("配置组 {Name} 加载完成,共{Cnt}个脚本,开始执行", groupName, list.Count); - - // 循环执行所有脚本 var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage; await new TaskRunner(timerOperation) - .RunThreadAsync(async () => - { - foreach (var project in list) - { - if (project.Status != "Enabled") - { - _logger.LogInformation("脚本 {Name} 状态为禁用,跳过执行", project.Name); - continue; - } - if (CancellationContext.Instance.Cts.IsCancellationRequested) - { - _logger.LogInformation("执行被取消"); - break; - } + .RunThreadAsync(async () => + { + foreach (var project in list) + { + if (project.Status != "Enabled") + { + _logger.LogInformation("脚本 {Name} 状态为禁用,跳过执行", project.Name); + continue; + } + if (CancellationContext.Instance.Cts.IsCancellationRequested) + { + _logger.LogInformation("执行被取消"); + break; + } - for (var i = 0; i < project.RunNum; i++) - { - try - { - if (hasTimer) - { - TaskTriggerDispatcher.Instance().ClearTriggers(); - } + for (var i = 0; i < project.RunNum; i++) + { + try + { + if (hasTimer) + { + TaskTriggerDispatcher.Instance().ClearTriggers(); + } - _logger.LogInformation("------------------------------"); + _logger.LogInformation("------------------------------"); - if (project.Type == "Javascript") - { - if (project.Project == null) - { - throw new Exception("Project 为空"); - } + await ExecuteProject(project); - _logger.LogInformation("→ 开始执行JS脚本: {Name}", project.Name); - await project.Run(); - } - else if (project.Type == "KeyMouse") - { - _logger.LogInformation("→ 开始执行键鼠脚本: {Name}", project.Name); - await project.Run(); - } - else if (project.Type == "Pathing") - { - _logger.LogInformation("→ 开始执行路径追踪任务: {Name}", project.Name); - await project.Run(); - } - - await Task.Delay(2000); - } - catch (Exception e) - { - _logger.LogDebug(e, "执行脚本时发生异常"); - _logger.LogError("执行脚本时发生异常: {Msg}", e.Message); - } - finally - { - _logger.LogInformation("→ 脚本执行结束: {Name}", project.Name); - _logger.LogInformation("------------------------------"); - } - } - } - }); + await Task.Delay(2000); + } + catch (Exception e) + { + _logger.LogDebug(e, "执行脚本时发生异常"); + _logger.LogError("执行脚本时发生异常: {Msg}", e.Message); + } + finally + { + _logger.LogInformation("→ 脚本执行结束: {Name}", project.Name); + _logger.LogInformation("------------------------------"); + } + } + } + }); _logger.LogInformation("配置组 {Name} 执行结束", groupName); } + private List ReloadScriptProjects(IEnumerable projectList, ref bool hasTimer) + { + var list = new List(); + foreach (var project in projectList) + { + if (project.Type == "Javascript") + { + var newProject = new ScriptGroupProject(new ScriptProject(project.FolderName)); + CopyProjectProperties(project, newProject); + list.Add(newProject); + } + else if (project.Type == "KeyMouse") + { + var newProject = ScriptGroupProject.BuildKeyMouseProject(project.FolderName); + CopyProjectProperties(project, newProject); + list.Add(newProject); + } + else if (project.Type == "Pathing") + { + var newProject = ScriptGroupProject.BuildPathingProject(project.Name, project.FolderName); + CopyProjectProperties(project, newProject); + list.Add(newProject); + hasTimer = true; + } + } + return list; + } + + private void CopyProjectProperties(ScriptGroupProject source, ScriptGroupProject target) + { + target.Status = source.Status; + target.Schedule = source.Schedule; + target.RunNum = source.RunNum; + target.JsScriptSettingsObject = source.JsScriptSettingsObject; + } + + private List ExtractJsProjects(List list) + { + var jsProjects = new List(); + foreach (var project in list) + { + if (project is { Type: "Javascript", Project: not null }) + { + jsProjects.Add(project.Project); + } + } + return jsProjects; + } + + private async Task ExecuteProject(ScriptGroupProject project) + { + if (project.Type == "Javascript") + { + if (project.Project == null) + { + throw new Exception("Project 为空"); + } + + _logger.LogInformation("→ 开始执行JS脚本: {Name}", project.Name); + await project.Run(); + } + else if (project.Type == "KeyMouse") + { + _logger.LogInformation("→ 开始执行键鼠脚本: {Name}", project.Name); + await project.Run(); + } + else if (project.Type == "Pathing") + { + _logger.LogInformation("→ 开始执行路径追踪任务: {Name}", project.Name); + await project.Run(); + } + } + private async Task> ReadCodeList(List list) { var codeList = new List(); diff --git a/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs index b591fe5d..63b9f6ce 100644 --- a/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs @@ -94,6 +94,6 @@ public partial class JsListViewModel : ObservableObject, INavigationAware, IView { return; } - await _scriptService.RunMulti([item.FolderName]); + await _scriptService.RunMultiJs([item.FolderName]); } } diff --git a/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs index 2a506794..baf55ec5 100644 --- a/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs @@ -1,10 +1,12 @@ using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Script; +using BetterGenshinImpact.Core.Script.Group; using BetterGenshinImpact.Core.Script.Project; using BetterGenshinImpact.GameTask; using BetterGenshinImpact.GameTask.AutoPathing; using BetterGenshinImpact.GameTask.AutoPathing.Model; using BetterGenshinImpact.GameTask.Model.Enum; +using BetterGenshinImpact.Service.Interface; using BetterGenshinImpact.View.Windows; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; @@ -20,7 +22,7 @@ using Wpf.Ui.Violeta.Controls; namespace BetterGenshinImpact.ViewModel.Pages; -public partial class MapPathingViewModel : ObservableObject, INavigationAware, IViewModel +public partial class MapPathingViewModel(IScriptService scriptService) : ObservableObject, INavigationAware, IViewModel { private readonly ILogger _logger = App.GetLogger(); public static readonly string PathJsonPath = Global.Absolute(@"User\AutoPathing"); @@ -90,19 +92,23 @@ public partial class MapPathingViewModel : ObservableObject, INavigationAware, I } [RelayCommand] - public void OnStart(PathingTask? item) + public async void OnStart(PathingTask? item) { if (item == null) { return; } - new TaskRunner(DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty) - .FireAndForget(async () => - { - TaskTriggerDispatcher.Instance().AddTrigger("AutoPick", null); - await new PathExecutor(CancellationContext.Instance.Cts).Pathing(item); - }); + // new TaskRunner(DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty) + // .FireAndForget(async () => + // { + // TaskTriggerDispatcher.Instance().AddTrigger("AutoPick", null); + // await new PathExecutor(CancellationContext.Instance.Cts).Pathing(item); + // }); + + var fileInfo = new FileInfo(item.FullPath); + var project = ScriptGroupProject.BuildPathingProject(fileInfo.Name, fileInfo.DirectoryName!); + await scriptService.RunMulti([project]); } [RelayCommand]