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