Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更新: Economics.Skill 添加执行js脚本 #387

Merged
merged 2 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Economics.Skill/Attributes/JavaScriptFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Economics.Skill.Attributes;

[AttributeUsage(AttributeTargets.Method)]
public class JavaScriptFunction : Attribute
{
public string Name { get; set; }

public JavaScriptFunction(string name)
{
Name = name;
}
}
12 changes: 9 additions & 3 deletions Economics.Skill/Economics.Skill.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Economics.RPG\Economics.RPG.csproj" />
<ProjectReference Include="..\EconomicsAPI\EconomicsAPI.csproj" />
<None Remove="lib\Acornima.dll" />
<None Remove="lib\Jint.dll" />
</ItemGroup>

<ItemGroup>
<Folder Include="lib\" />
<EmbeddedResource Include="lib\Acornima.dll" />
<EmbeddedResource Include="lib\Jint.dll" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Economics.RPG\Economics.RPG.csproj" />
<ProjectReference Include="..\EconomicsAPI\EconomicsAPI.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
70 changes: 70 additions & 0 deletions Economics.Skill/JSInterpreter/Interpreter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using Terraria;
using Jint;
using TShockAPI;
using Economics.Skill.Attributes;
using System.Reflection;
using System.Linq.Expressions;
using Economics.Skill.Model;
using Microsoft.Xna.Framework;

namespace Economics.Skill.JSInterpreter;

public class Interpreter
{
private static readonly Engine Engine = new Engine((o) =>
{
o.AllowClr(typeof(EconomicsAPI.Economics).Assembly,
typeof(TShock).Assembly,
typeof(Task).Assembly,
typeof(List<>).Assembly,
typeof(Main).Assembly);
o.AddExtensionMethods(typeof(EconomicsAPI.Extensions.Vector2Ext),
typeof(EconomicsAPI.Extensions.GameProgress),
typeof(Terraria.Utils),
typeof(EconomicsAPI.Extensions.PlayerExt),
typeof(EconomicsAPI.Extensions.NpcExt),
typeof(Enumerable),
typeof(EconomicsAPI.Extensions.TSPlayerExt));
});

public static readonly string ScriptsDir = Path.Combine(EconomicsAPI.Economics.SaveDirPath, "SkillScripts");
static Interpreter()
{
if(!Directory.Exists(ScriptsDir))
Directory.CreateDirectory(ScriptsDir);
}

/// <summary>
/// 加载预定义JS函数
/// </summary>
public static void LoadFunction()
{
foreach (var method in typeof(JSFunctions).GetMethods())
{
var func = method.GetCustomAttribute<JavaScriptFunction>();
if (method.IsStatic && func != null)
{
var tyep = Expression.GetDelegateType(method.GetParameters().Select(x => x.ParameterType).Append(method.ReturnType).ToArray());
Engine.SetValue(func.Name, method.CreateDelegate(tyep, null));
}
}
}

public static void ExecuteScript(SkillContext skill,TSPlayer player, Vector2 pos, Vector2 vel)
{
if (skill.JsScript == null || string.IsNullOrEmpty(skill.JsScript.Script))
{
return;
}
try
{
Engine.Evaluate(skill.JsScript.Script);
Engine.Invoke("main", skill, player, pos, vel);
}
catch (Exception ex)
{
TShock.Log.ConsoleError(skill.JsScript.FilePathOrUri + "执行错误:" + ex);
}
}

}
53 changes: 53 additions & 0 deletions Economics.Skill/JSInterpreter/JSFunctions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Economics.Skill.Attributes;
using Microsoft.Xna.Framework;
using NuGet.Configuration;
using Terraria;
using TShockAPI;

namespace Economics.Skill.JSInterpreter;

public class JSFunctions
{
[JavaScriptFunction("print")]
public static void JSPrint(string message) => Console.WriteLine(message);


[JavaScriptFunction("SpawnProjtile")]
public static int JSProj(TSPlayer ply, Vector2 pos, Vector2 vel, int type, int Damage, int KnockBack, int Owner, float ai0 = 0, float ai1 = 0, float ai2 = 0, int timeLeft = -1, string uuid = "")
{
return EconomicsAPI.Utils.SpawnProjectile.NewProjectile(
//发射原无期
ply.TPlayer.GetProjectileSource_Item(ply.TPlayer.HeldItem),
//发射位置
pos,
vel,
type,
Damage,
KnockBack,
Owner,
ai0,
ai1,
ai2,
timeLeft,
uuid);
}


[JavaScriptFunction("SendProjectilePacket")]
public static void SendProjectilePacket(int index)
{
TSPlayer.All.SendData(PacketTypes.ProjectileNew, "", index);
}


[JavaScriptFunction("SendPacket")]
public static void SendPacket(int packetid, int num, int num2, int num3, int num4, int num5, int num6, int num7)
{
NetMessage.SendData(packetid, -1, -1, null, num, num2, num5, num5, num6, num7);
}
}
17 changes: 17 additions & 0 deletions Economics.Skill/JSInterpreter/JsScript.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Economics.Skill.JSInterpreter;

public class JsScript
{
public string FilePathOrUri { get; set; } = string.Empty;

public int ReferenceCount { get; set; }

public string Script { get; set; } = string.Empty;

public List<string> PackageRequirements { get; set; }

public JsScript()
{
PackageRequirements = new List<string>();
}
}
11 changes: 11 additions & 0 deletions Economics.Skill/JSInterpreter/PreprocessorDirectives.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Text.RegularExpressions;

namespace Economics.Skill.JSInterpreter;

internal static class PreprocessorDirectives
{

public static readonly Regex importRegex = new("@import \"(.*?)\";");

public static readonly Regex requiresRegex = new("@require(s?) (.*?);");
}
37 changes: 37 additions & 0 deletions Economics.Skill/JSInterpreter/ScriptContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Text.RegularExpressions;

namespace Economics.Skill.JSInterpreter;

public class ScriptContainer
{
public static void PreprocessScript(JsScript script)
{
if (script != null && !string.IsNullOrEmpty(script.Script))
{
PreprocessRequires(script);
}
}

public static void PreprocessRequires(JsScript script)
{
if (script == null || string.IsNullOrEmpty(script.Script) || !PreprocessorDirectives.requiresRegex.IsMatch(script.Script))
{
return;
}
foreach (Match item in PreprocessorDirectives.requiresRegex.Matches(script.Script))
{
string[] array = item.Groups[2].Value.Split(',');
string[] array2 = array;
foreach (string text in array2)
{
string text2 = text.Trim().Replace("\"", "");
if (string.IsNullOrEmpty(text2))
{
return;
}
script.PackageRequirements.Add(text2);
script.Script = script.Script.Replace(item.Value, $"/** #pragma require \"{text2}\" - DO NOT CHANGE THIS LINE **/\r\n");
}
}
}
}
35 changes: 34 additions & 1 deletion Economics.Skill/Model/SkillContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Economics.Skill.Model.Options;
using Economics.Skill.JSInterpreter;
using Economics.Skill.Model.Options;
using Economics.Skill.Model.Options.Projectile;
using Economics.Skill.Model.Options.Range;
using EconomicsAPI.Extensions;
Expand Down Expand Up @@ -61,9 +62,41 @@ public class SkillContext
[JsonProperty("范围Buff")]
public BuffOption BuffOption { get; set; } = new();

[JsonProperty("执行脚本")]
public string? ExecuteScript
{
get { return JsScript?.FilePathOrUri; }
set
{
JsScript = Set(value);
}
}

[JsonProperty("弹幕")]
public List<ProjectileOption> Projectiles { get; set; } = new();

[JsonIgnore]
public JsScript? JsScript { get; set; }

public JsScript? Set(string? path)
{
var jistScript = new JsScript
{
FilePathOrUri = path
};
try
{
jistScript.Script = File.ReadAllText(Path.Combine(Interpreter.ScriptsDir, jistScript.FilePathOrUri));
}
catch (Exception ex)
{
TShock.Log.Error("无法加载{0}: {1}", path, ex.Message);
return null;
}
ScriptContainer.PreprocessRequires(jistScript);
return jistScript;
}

public void AddNpcBuff(TSPlayer Player)
{
if (NpcBuff.Enable)
Expand Down
33 changes: 27 additions & 6 deletions Economics.Skill/Skill.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Economics.Skill.DB;
using Economics.Skill.Events;
using Economics.Skill.JSInterpreter;
using Economics.Skill.Setting;
using EconomicsAPI.Configured;
using EconomicsAPI.EventArgs.PlayerEventArgs;
using Jint;
using System.Reflection;
using Terraria;
using TerrariaApi.Server;
Expand All @@ -21,9 +21,7 @@ public class Skill : TerrariaPlugin

public override string Name => Assembly.GetExecutingAssembly().GetName().Name!;

public override Version Version => new(1, 2, 1, 0);

public static readonly Engine Script = new();
public override Version Version => new(1, 2, 1, 1);

internal static string PATH = Path.Combine(EconomicsAPI.Economics.SaveDirPath, "Skill.json");

Expand All @@ -35,13 +33,28 @@ public class Skill : TerrariaPlugin

public Skill(Main game) : base(game)
{

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}

private Assembly? CurrentDomain_AssemblyResolve(object? sender, ResolveEventArgs args)
{
string resourceName = $"{Assembly.GetExecutingAssembly().GetName().Name}.lib.{new AssemblyName(args.Name).Name}.dll";
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
if (stream != null)
{
byte[] assemblyData = new byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
return null;
}

public override void Initialize()
{
LoadConfig();

PlayerSKillManager = new();
ServerApi.Hooks.GamePostInitialize.Register(this, OnPost);
ServerApi.Hooks.NpcStrike.Register(this, OnStrike);
ServerApi.Hooks.GameUpdate.Register(this, OnUpdate);
ServerApi.Hooks.ProjectileAIUpdate.Register(this, OnAiUpdate);
Expand All @@ -53,10 +66,18 @@ public override void Initialize()
GetDataHandlers.PlayerDamage.Register(OnPlayerDamage);
EconomicsAPI.Events.PlayerHandler.OnPlayerKillNpc += OnKillNpc;
EconomicsAPI.Events.PlayerHandler.OnPlayerCountertop += OnPlayerCountertop;
GeneralHooks.ReloadEvent += e => LoadConfig();
GeneralHooks.ReloadEvent += e =>
{
LoadConfig();
};
On.Terraria.Projectile.Update += Projectile_Update;
}

private void OnPost(EventArgs args)
{
Interpreter.LoadFunction();
}

private void OnPlayerDamage(object? sender, GetDataHandlers.PlayerDamageEventArgs e)
{
PlayerSparkSkillHandler.Adapter(e.Player, Enumerates.SkillSparkType.Struck);
Expand Down
3 changes: 3 additions & 0 deletions Economics.Skill/Utils.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Economics.Skill.Enumerates;
using Economics.Skill.JSInterpreter;
using Economics.Skill.Model;
using EconomicsAPI.Extensions;
using Microsoft.Xna.Framework;
Expand Down Expand Up @@ -154,6 +155,7 @@ public static void EmitSkill(TSPlayer Player, SkillContext skill)
//原始角度速度参数
var vel = Player.TPlayer.ItemOffSet();
SpawnSkillProjectile(Player, skill, vel, pos);
Interpreter.ExecuteScript(skill, Player, pos, vel);
}

public static void EmitSkill(GetDataHandlers.NewProjectileEventArgs e, SkillContext skill)
Expand All @@ -163,5 +165,6 @@ public static void EmitSkill(GetDataHandlers.NewProjectileEventArgs e, SkillCont
//原始角度速度参数
var vel = e.Velocity;
SpawnSkillProjectile(e.Player, skill, vel, pos);
Interpreter.ExecuteScript(skill, e.Player, pos, vel);
}
}
Loading
Loading