update: 更新到godot4.4.1,并大量重构代码
This commit is contained in:
69
Scripts/Mods/GlobalModManager.cs
Normal file
69
Scripts/Mods/GlobalModManager.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using Godot;
|
||||
using NLua;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
public class GlobalModManager
|
||||
{
|
||||
public readonly Lua lua = new();
|
||||
private readonly string modsPath;
|
||||
|
||||
public GlobalModManager(string modsPath = "user://Mods/") {
|
||||
this.modsPath = modsPath;
|
||||
lua.State.Encoding = Encoding.UTF8;
|
||||
// lua.State.SetHook(KeraLua.LuaHookMask.Count, 1000000);
|
||||
|
||||
InitSandBox();
|
||||
// RegisterAPI();
|
||||
}
|
||||
|
||||
public void LoadAllMods()
|
||||
{
|
||||
if (!DirAccess.DirExistsAbsolute(modsPath))
|
||||
return;
|
||||
|
||||
using var dir = DirAccess.Open(modsPath);
|
||||
if (dir == null) return;
|
||||
|
||||
dir.ListDirBegin();
|
||||
string fileName = dir.GetNext();
|
||||
while (!string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
if (fileName.EndsWith(".lua"))
|
||||
{
|
||||
LoadMod(fileName);
|
||||
}
|
||||
fileName = dir.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitSandBox() {
|
||||
}
|
||||
|
||||
private void LoadMod(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
string luaCode = LoadFile(filePath);
|
||||
lua.DoString(luaCode);
|
||||
GD.Print($"成功加载Mod: {filePath}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GD.PrintErr($"加载Mod {filePath} 失败: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void SaveFile(string path, string content)
|
||||
{
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
||||
file.StoreString(content);
|
||||
}
|
||||
|
||||
private static string LoadFile(string path)
|
||||
{
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
string content = file.GetAsText();
|
||||
return content;
|
||||
}
|
||||
}
|
1
Scripts/Mods/GlobalModManager.cs.uid
Normal file
1
Scripts/Mods/GlobalModManager.cs.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://c45a7ldunixnh
|
40
Scripts/Mods/LuaModManager.cs
Normal file
40
Scripts/Mods/LuaModManager.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using NLua;
|
||||
|
||||
class LuaMod : IDisposable {
|
||||
private readonly Lua lua = new();
|
||||
|
||||
public LuaMod(string path, string? package_path = null) {
|
||||
lua.LoadCLRPackage();
|
||||
lua.State.Encoding = System.Text.Encoding.UTF8;
|
||||
lua["package.path"] = package_path ?? Path.GetDirectoryName(path) + "/?.lua;";
|
||||
lua.RegisterFunction("print", new Action<object[]>(GD.Print).Method);
|
||||
// Action bar = () => { GD.Print("bar"); };
|
||||
// lua.RegisterFunction("bar", bar.Target, bar.Method);
|
||||
lua.DoFile(path);
|
||||
}
|
||||
|
||||
public void BindFunc(ModManager mod) {
|
||||
foreach (var api in mod.GetAPIs()) {
|
||||
lua.RegisterFunction(api.Key, api.Value.Target, api.Value.Method);
|
||||
}
|
||||
foreach (var hook in mod.GetHooks()) {
|
||||
if (lua[hook.Key] is LuaFunction func) {
|
||||
mod.AddHook(hook.Key, (args) => {
|
||||
var rets = func.Call(args).FirstOrDefault();
|
||||
if (rets is bool b) return b;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
lua?.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
1
Scripts/Mods/LuaModManager.cs.uid
Normal file
1
Scripts/Mods/LuaModManager.cs.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://dtqaboju24vmn
|
45
Scripts/Mods/ModManager.cs
Normal file
45
Scripts/Mods/ModManager.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
|
||||
class ModManager {
|
||||
private readonly Dictionary<string, Delegate> _api = [];
|
||||
private readonly Dictionary<string, Delegate> _hooks = [];
|
||||
public delegate bool OnCallback(params object[] args);
|
||||
private readonly Dictionary<string, List<OnCallback>> _callbackList = [];
|
||||
|
||||
public ReadOnlyDictionary<string, Delegate> GetAPIs() => new(_api);
|
||||
public ReadOnlyDictionary<string, Delegate> GetHooks() => new(_hooks);
|
||||
|
||||
public ModManager RegistryFunc<TDelegate>(string name, TDelegate handler, bool isHook = false)
|
||||
where TDelegate : Delegate {
|
||||
MethodInfo _ = handler.Method;
|
||||
Dictionary<string, Delegate> dict = isHook ? _hooks : _api;
|
||||
dict.Add(name, handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool AddHook(string name, OnCallback handler) {
|
||||
if (_hooks.ContainsKey(name)) {
|
||||
if (!_callbackList.TryGetValue(name, out var list)) {
|
||||
list = [];
|
||||
_callbackList[name] = list;
|
||||
}
|
||||
list.Add(handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool InvokeFunc<TDelegate>(string name, params object[] args)
|
||||
where TDelegate : Delegate {
|
||||
List<object> res = [];
|
||||
if (_callbackList.TryGetValue(name, out var callback)) {
|
||||
foreach (var func in callback) {
|
||||
func?.Invoke(args);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
1
Scripts/Mods/ModManager.cs.uid
Normal file
1
Scripts/Mods/ModManager.cs.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://lmuddan86bi8
|
Reference in New Issue
Block a user