diff --git a/BetterGenshinImpact/Model/Gear/BaseGearTask.cs b/BetterGenshinImpact/Model/Gear/BaseGearTask.cs index 1e593f44..5ae695af 100644 --- a/BetterGenshinImpact/Model/Gear/BaseGearTask.cs +++ b/BetterGenshinImpact/Model/Gear/BaseGearTask.cs @@ -23,9 +23,9 @@ public abstract class BaseGearTask : ObservableObject public string Name { get; set; } = string.Empty; /// - /// 任务的位置相对 User 目录下的路径 + /// 任务的文件位置,如果有 /// - public string RelativePath { get; set; } = string.Empty; + public string FilePath { get; set; } = string.Empty; /// /// 任务是否启用 @@ -45,14 +45,14 @@ public abstract class BaseGearTask : ObservableObject /// /// 执行任务 /// - public async Task Execute() + public async Task Execute(params object[] configs) { var stopwatch = new Stopwatch(); try { _logger.LogInformation("------------------------------"); stopwatch.Start(); - await Run(); + await Run(configs); } catch (NormalEndException e) { @@ -81,5 +81,11 @@ public abstract class BaseGearTask : ObservableObject /// /// 执行任务 /// - public abstract Task Run(); -} \ No newline at end of file + public abstract Task Run(params object[] configs); + + + // /// + // /// 读取详情内容 + // /// + // public abstract string ReadDetail(); +} diff --git a/BetterGenshinImpact/Model/Gear/JavascriptGearTask.cs b/BetterGenshinImpact/Model/Gear/JavascriptGearTask.cs new file mode 100644 index 00000000..2238b291 --- /dev/null +++ b/BetterGenshinImpact/Model/Gear/JavascriptGearTask.cs @@ -0,0 +1,101 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using BetterGenshinImpact.Core.Config; +using BetterGenshinImpact.Core.Script; +using BetterGenshinImpact.Core.Script.Dependence; +using BetterGenshinImpact.Core.Script.Project; +using Microsoft.ClearScript; +using Microsoft.ClearScript.V8; + +namespace BetterGenshinImpact.Model.Gear; + +public class JavascriptGearTask : BaseGearTask +{ + public string ProjectPath { get; set; } + + public Manifest Manifest { get; set; } + + public string FolderName { get; set; } + + public JavascriptGearTask(string folderName) + { + FolderName = folderName; + ProjectPath = Path.Combine(Global.ScriptPath(), folderName); + if (!Directory.Exists(ProjectPath)) + { + throw new DirectoryNotFoundException("脚本文件夹不存在:" + ProjectPath); + } + + var manifestFile = Path.GetFullPath(Path.Combine(ProjectPath, "manifest.json")); + if (!File.Exists(manifestFile)) + { + throw new FileNotFoundException("manifest.json文件不存在,请确认此脚本是JS脚本类型。" + manifestFile); + } + + Manifest = Manifest.FromJson(File.ReadAllText(manifestFile)); + Manifest.Validate(ProjectPath); + + // 基础属性 + Name = folderName; + FilePath = Path.Combine(Global.ScriptPath(), folderName); + } + + public override async Task Run(params object[] configs) + { + await ExecuteScriptAsync(configs[0], (PathingPartyConfig)configs[1]); + } + + // public override string ReadDetail() + // { + // throw new NotImplementedException(); + // } + + private async Task ExecuteScriptAsync(dynamic? context = null, PathingPartyConfig? partyConfig = null) + { + // 默认值 + GlobalMethod.SetGameMetrics(1920, 1080); + // 加载代码 + var code = await LoadCode(); + var engine = BuildScriptEngine(partyConfig); + if (context != null) + { + // 写入配置的内容 + engine.AddHostObject("settings", context); + } + + try + { + await (Task)engine.Evaluate(code); + } + catch (Exception e) + { + Debug.WriteLine(e); + throw; + } + finally + { + engine.Dispose(); + } + } + + private IScriptEngine BuildScriptEngine(PathingPartyConfig? partyConfig = null) + { + IScriptEngine engine = new V8ScriptEngine(V8ScriptEngineFlags.UseCaseInsensitiveMemberBinding | + V8ScriptEngineFlags.EnableTaskPromiseConversion); + EngineExtend.InitHost(engine, ProjectPath, Manifest.Library, partyConfig); + return engine; + } + + private async Task LoadCode() + { + var code = await File.ReadAllTextAsync(Path.Combine(ProjectPath, Manifest.Main)); + if (string.IsNullOrEmpty(code)) + { + throw new FileNotFoundException("main js is empty."); + } + + return code; + } +} \ No newline at end of file