diff --git a/CheatEnabler/CheatEnabler.csproj b/CheatEnabler/CheatEnabler.csproj index 9f08495..49ecb83 100644 --- a/CheatEnabler/CheatEnabler.csproj +++ b/CheatEnabler/CheatEnabler.csproj @@ -29,6 +29,6 @@ - + diff --git a/DSP_Mods.sln b/DSP_Mods.sln index f1fa876..ebcd76b 100644 --- a/DSP_Mods.sln +++ b/DSP_Mods.sln @@ -34,6 +34,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UXAssist", "UXAssist\UXAssi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserCloak", "UserCloak\UserCloak.csproj", "{096D2E4B-D1CE-424D-9954-C36A23E9E279}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaScriptEngine", "LuaScriptEngine\LuaScriptEngine.csproj", "{E9375F0E-26DC-4CEC-80DC-9C48F23340BC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -96,5 +98,9 @@ Global {096D2E4B-D1CE-424D-9954-C36A23E9E279}.Debug|Any CPU.Build.0 = Debug|Any CPU {096D2E4B-D1CE-424D-9954-C36A23E9E279}.Release|Any CPU.ActiveCfg = Release|Any CPU {096D2E4B-D1CE-424D-9954-C36A23E9E279}.Release|Any CPU.Build.0 = Release|Any CPU + {E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Dustbin/Dustbin.csproj b/Dustbin/Dustbin.csproj index 8633170..2c878f9 100644 --- a/Dustbin/Dustbin.csproj +++ b/Dustbin/Dustbin.csproj @@ -33,6 +33,6 @@ - + diff --git a/HideTips/HideTips.csproj b/HideTips/HideTips.csproj index 55f6188..0f069ac 100644 --- a/HideTips/HideTips.csproj +++ b/HideTips/HideTips.csproj @@ -24,6 +24,6 @@ - + diff --git a/LabOpt/LabOpt.csproj b/LabOpt/LabOpt.csproj index 21129e0..b383fbf 100644 --- a/LabOpt/LabOpt.csproj +++ b/LabOpt/LabOpt.csproj @@ -24,6 +24,6 @@ - + diff --git a/LuaScriptEngine/CHANGELOG.md b/LuaScriptEngine/CHANGELOG.md new file mode 100644 index 0000000..83aadba --- /dev/null +++ b/LuaScriptEngine/CHANGELOG.md @@ -0,0 +1,7 @@ +## Changlog +* 1.0.0 + + Initial release + +## 更新日志 +* 1.0.0 + + 初始版本 diff --git a/LuaScriptEngine/LuaScriptEngine.cs b/LuaScriptEngine/LuaScriptEngine.cs new file mode 100644 index 0000000..0b1b656 --- /dev/null +++ b/LuaScriptEngine/LuaScriptEngine.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using BepInEx; +using BepInEx.Logging; +using HarmonyLib; +using NLua; + +namespace LuaScriptEngine; + +[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] +public class LuaScriptEngine : BaseUnityPlugin +{ + private class Timer + { + public Timer(LuaFunction func, long startInterval, long repeatInterval = 0L) + { + _func = func; + _repeatInterval = repeatInterval; + _nextTick = GameMain.gameTick + startInterval; + } + + public bool Check(long gameTick) + { + if (gameTick < _nextTick) return false; + try + { + _func.Call(); + } + catch (Exception e) + { + Logger.LogError($"Error in Lua script: {e}"); + } + + if (_repeatInterval <= 0L) return true; + _nextTick += _repeatInterval; + if (_nextTick < gameTick) + _nextTick = gameTick + 1; + return false; + } + + private readonly LuaFunction _func; + private readonly long _repeatInterval; + private long _nextTick; + } + public new static readonly ManualLogSource Logger = + BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); + + private Harmony _harmony; + + private static readonly Lua LuaState = new(); + private static readonly List PreUpdateFuncs = []; + private static readonly List PostUpdateFuncs = []; + private static readonly List PreGameBeginFuncs = []; + private static readonly List PostGameBeginFuncs = []; + private static readonly List PreGameEndFuncs = []; + private static readonly List PostGameEndFuncs = []; + private static readonly List Timers = []; + private static readonly List RemovedTimers = []; + + private void Awake() + { + LuaState.LoadCLRPackage(); + LuaState.DoString("import('Assembly-CSharp')"); + LuaState["register_callback"] = (string tp, bool pre, LuaFunction action) => + { + switch (tp) + { + case "update": + (pre ? PreUpdateFuncs : PostUpdateFuncs).Add(action); + break; + case "game_begin": + (pre ? PreGameBeginFuncs : PostGameBeginFuncs).Add(action); + break; + case "game_end": + (pre ? PreGameEndFuncs : PostGameEndFuncs).Add(action); + break; + } + }; + LuaState["add_timer"] = int(LuaFunction func, long firstInterval, long repeatInterval) => + { + var timer = new Timer(func, firstInterval, repeatInterval); + if (RemovedTimers.Count <= 0) + { + Timers.Add(timer); + return Timers.Count - 1; + } + var index = RemovedTimers[RemovedTimers.Count - 1]; + Timers[index] = timer; + RemovedTimers.RemoveAt(RemovedTimers.Count - 1); + return index; + }; + LuaState["remove_timer"] = void (int index) => + { + if (index < 0 || index >= Timers.Count) return; + Timers[index] = null; + RemovedTimers.Add(index); + }; + + var assemblyPath = System.IO.Path.Combine( + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)!, + "scripts" + ); + + foreach (var file in System.IO.Directory.GetFiles(assemblyPath, "*.lua")) + { + Logger.LogInfo($"Loading Lua script: {file}"); + LuaState.DoFile(file); + } + _harmony = Harmony.CreateAndPatchAll(typeof(Patches)); + } + + private void OnDestroy() + { + RemovedTimers.Clear(); + Timers.Clear(); + PreUpdateFuncs.Clear(); + PostUpdateFuncs.Clear(); + PreGameBeginFuncs.Clear(); + PostGameBeginFuncs.Clear(); + PreGameEndFuncs.Clear(); + PostGameEndFuncs.Clear(); + + _harmony?.UnpatchSelf(); + LuaState.Dispose(); + } + + private static class Patches + { + private static void LoopCall(List funcs) + { + foreach (var func in funcs) + { + try + { + func.Call(); + } + catch (Exception e) + { + Logger.LogError($"Error in Lua script: {e}"); + } + } + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.FixedUpdate))] + private static void GameMain_FixedUpdate_Prefix() + { + if (Timers.Count > 0) + { + var gameTick = GameMain.gameTick; + for (var index = Timers.Count - 1; index >= 0; index--) + { + var timer = Timers[index]; + if (timer == null || !timer.Check(gameTick)) continue; + Timers[index] = null; + RemovedTimers.Add(index); + } + } + + LoopCall(PreUpdateFuncs); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.FixedUpdate))] + private static void GameMain_FixedUpdate_Postfix() + { + LoopCall(PostUpdateFuncs); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] + private static void GameMain_Begin_Prefix() + { + LoopCall(PreGameBeginFuncs); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] + private static void GameMain_Begin_Postfix() + { + LoopCall(PostGameBeginFuncs); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] + private static void GameMain_End_Prefix() + { + LoopCall(PreGameEndFuncs); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] + private static void GameMain_End_Postfix() + { + LoopCall(PostGameEndFuncs); + } + } +} \ No newline at end of file diff --git a/LuaScriptEngine/LuaScriptEngine.csproj b/LuaScriptEngine/LuaScriptEngine.csproj new file mode 100644 index 0000000..29d55b3 --- /dev/null +++ b/LuaScriptEngine/LuaScriptEngine.csproj @@ -0,0 +1,30 @@ + + + + + net472 + LuaScriptEngine + org.soardev.luascriptengine + DSP MOD - LuaScriptEngine + 1.0.0 + true + latest + https://nuget.bepinex.dev/v3/index.json + + + + + + + + + + + + + + + + + + diff --git a/LuaScriptEngine/README.md b/LuaScriptEngine/README.md new file mode 100644 index 0000000..a7a1119 --- /dev/null +++ b/LuaScriptEngine/README.md @@ -0,0 +1,8 @@ +# LuaScriptEngine + +#### Write mod functions in lua scripts +#### 用lua脚本编写mod功能 + +## Usage + +## 使用说明 diff --git a/LuaScriptEngine/package/icon.png b/LuaScriptEngine/package/icon.png new file mode 100644 index 0000000..84fa77d Binary files /dev/null and b/LuaScriptEngine/package/icon.png differ diff --git a/LuaScriptEngine/package/manifest.json b/LuaScriptEngine/package/manifest.json new file mode 100644 index 0000000..27ea4d4 --- /dev/null +++ b/LuaScriptEngine/package/manifest.json @@ -0,0 +1,9 @@ +{ + "name": "LuaScriptEngine", + "version_number": "1.0.0", + "website_url": "https://github.com/soarqin/DSP_Mods/tree/master/LuaScriptEngine", + "description": "Write mod functions in lua scripts / 用lua脚本编写mod功能", + "dependencies": [ + "xiaoye97-BepInEx-5.4.17" + ] +} diff --git a/MechaDronesTweaks/MechaDronesTweaks.csproj b/MechaDronesTweaks/MechaDronesTweaks.csproj index 9ff8c51..a286cae 100644 --- a/MechaDronesTweaks/MechaDronesTweaks.csproj +++ b/MechaDronesTweaks/MechaDronesTweaks.csproj @@ -24,6 +24,6 @@ - + diff --git a/OCBatchBuild/OCBatchBuild.csproj b/OCBatchBuild/OCBatchBuild.csproj index e7101f7..988e55e 100644 --- a/OCBatchBuild/OCBatchBuild.csproj +++ b/OCBatchBuild/OCBatchBuild.csproj @@ -24,6 +24,6 @@ - + diff --git a/OverclockEverything/OverclockEverything.csproj b/OverclockEverything/OverclockEverything.csproj index 9c1a6f0..a61565f 100644 --- a/OverclockEverything/OverclockEverything.csproj +++ b/OverclockEverything/OverclockEverything.csproj @@ -26,6 +26,6 @@ - + diff --git a/PoolOpt/PoolOpt.csproj b/PoolOpt/PoolOpt.csproj index 53c64c5..1f447d2 100644 --- a/PoolOpt/PoolOpt.csproj +++ b/PoolOpt/PoolOpt.csproj @@ -24,6 +24,6 @@ - + diff --git a/UXAssist/UXAssist.csproj b/UXAssist/UXAssist.csproj index 70bce5a..427f444 100644 --- a/UXAssist/UXAssist.csproj +++ b/UXAssist/UXAssist.csproj @@ -37,6 +37,6 @@ - + diff --git a/UniverseGenTweaks/UniverseGenTweaks.csproj b/UniverseGenTweaks/UniverseGenTweaks.csproj index 46433b8..66c6a39 100644 --- a/UniverseGenTweaks/UniverseGenTweaks.csproj +++ b/UniverseGenTweaks/UniverseGenTweaks.csproj @@ -29,6 +29,6 @@ - + diff --git a/UserCloak/UserCloak.csproj b/UserCloak/UserCloak.csproj index b64603b..36ba930 100644 --- a/UserCloak/UserCloak.csproj +++ b/UserCloak/UserCloak.csproj @@ -24,6 +24,6 @@ - +