From a8a0c96d571cd7dd7630eb8ed5157b2abf140c5a Mon Sep 17 00:00:00 2001
From: Evil Factory <36804725+evilfactory@users.noreply.github.com>
Date: Thu, 4 Nov 2021 11:30:36 -0300
Subject: [PATCH] move most of the registration code to Lua, include harmony,
add useful perf methods to Time and a more useful(but still useless) error
handling in the hook call
---
.../BarotraumaClient/LinuxClient.csproj | 1 +
Barotrauma/BarotraumaClient/MacClient.csproj | 1 +
.../BarotraumaClient/WindowsClient.csproj | 1 +
.../BarotraumaServer/LinuxServer.csproj | 1 +
Barotrauma/BarotraumaServer/MacServer.csproj | 1 +
.../BarotraumaServer/ServerSource/GameMain.cs | 7 +-
.../BarotraumaServer/WindowsServer.csproj | 1 +
.../BarotraumaShared/Lua/.vscode/launch.json | 11 +
.../Lua/.vscode/settings.json | 39 +++
.../BarotraumaShared/Lua/DefaultLib.lua | 56 ++++
.../BarotraumaShared/Lua/DefaultRegister.lua | 157 +++++++++++
.../Lua/{MoonsharpSetup.lua => LuaSetup.lua} | 12 +-
Barotrauma/BarotraumaShared/Lua/NluaSetup.lua | 0
.../SharedSource/Lua/LuaClasses.cs | 168 +++++++++++-
.../SharedSource/Lua/LuaSetup.cs | 254 +++---------------
15 files changed, 481 insertions(+), 229 deletions(-)
create mode 100644 Barotrauma/BarotraumaShared/Lua/.vscode/launch.json
create mode 100644 Barotrauma/BarotraumaShared/Lua/.vscode/settings.json
create mode 100644 Barotrauma/BarotraumaShared/Lua/DefaultLib.lua
create mode 100644 Barotrauma/BarotraumaShared/Lua/DefaultRegister.lua
rename Barotrauma/BarotraumaShared/Lua/{MoonsharpSetup.lua => LuaSetup.lua} (89%)
delete mode 100644 Barotrauma/BarotraumaShared/Lua/NluaSetup.lua
diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj
index d7446d96c..6c3780e94 100644
--- a/Barotrauma/BarotraumaClient/LinuxClient.csproj
+++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj
@@ -121,6 +121,7 @@
+
diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj
index 9e8888dc5..6640759d6 100644
--- a/Barotrauma/BarotraumaClient/MacClient.csproj
+++ b/Barotrauma/BarotraumaClient/MacClient.csproj
@@ -122,6 +122,7 @@
+
diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj
index f768ce3e1..0a16bfdca 100644
--- a/Barotrauma/BarotraumaClient/WindowsClient.csproj
+++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj
@@ -125,6 +125,7 @@
+
diff --git a/Barotrauma/BarotraumaServer/LinuxServer.csproj b/Barotrauma/BarotraumaServer/LinuxServer.csproj
index 7c5ab18b1..c25ba6e32 100644
--- a/Barotrauma/BarotraumaServer/LinuxServer.csproj
+++ b/Barotrauma/BarotraumaServer/LinuxServer.csproj
@@ -74,6 +74,7 @@
+
diff --git a/Barotrauma/BarotraumaServer/MacServer.csproj b/Barotrauma/BarotraumaServer/MacServer.csproj
index 246a1e1b6..248219178 100644
--- a/Barotrauma/BarotraumaServer/MacServer.csproj
+++ b/Barotrauma/BarotraumaServer/MacServer.csproj
@@ -89,6 +89,7 @@
+
diff --git a/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs b/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs
index d8ca89639..d4ce0ca29 100644
--- a/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs
+++ b/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs
@@ -364,7 +364,7 @@ namespace Barotrauma
{
DebugConsole.NewMessage("WARNING: Stopwatch frequency under 1500 ticks per second. Expect significant syncing accuracy issues.", Color.Yellow);
}
-
+ Stopwatch performanceMeasurement = new Stopwatch();
stopwatch = Stopwatch.StartNew();
long prevTicks = stopwatch.ElapsedTicks;
while (ShouldRun)
@@ -380,6 +380,8 @@ namespace Barotrauma
prevTicks = currTicks;
while (Timing.Accumulator >= Timing.Step)
{
+ performanceMeasurement.Start();
+
Timing.TotalTime += Timing.Step;
DebugConsole.Update();
if (GameSession?.GameMode == null || !GameSession.GameMode.Paused)
@@ -393,6 +395,9 @@ namespace Barotrauma
CoroutineManager.Update((float)Timing.Step, (float)Timing.Step);
GameMain.Lua.hook.Call("think", new object[] { });
+ performanceMeasurement.Stop();
+ LuaSetup.LuaTimer.LastUpdateTime = performanceMeasurement.ElapsedMilliseconds;
+ performanceMeasurement.Reset();
Timing.Accumulator -= Timing.Step;
}
diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj
index 5793a4254..5a0f09221 100644
--- a/Barotrauma/BarotraumaServer/WindowsServer.csproj
+++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj
@@ -83,6 +83,7 @@
+
diff --git a/Barotrauma/BarotraumaShared/Lua/.vscode/launch.json b/Barotrauma/BarotraumaShared/Lua/.vscode/launch.json
new file mode 100644
index 000000000..bd4a5a056
--- /dev/null
+++ b/Barotrauma/BarotraumaShared/Lua/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "MoonSharp Attach",
+ "type": "moonsharp-debug",
+ "debugServer": 41912,
+ "request": "attach"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaShared/Lua/.vscode/settings.json b/Barotrauma/BarotraumaShared/Lua/.vscode/settings.json
new file mode 100644
index 000000000..6bff2e0b1
--- /dev/null
+++ b/Barotrauma/BarotraumaShared/Lua/.vscode/settings.json
@@ -0,0 +1,39 @@
+{
+ "Lua.diagnostics.globals": [
+ "Game",
+ "Player",
+ "Random",
+ "Hook",
+ "Timer",
+ "bit32",
+ "TotalTime",
+ "DoFile",
+ "WayPoint",
+ "SpawnType",
+ "Level",
+ "Submarine",
+ "Vector2",
+ "PositionType",
+ "ServerLog_MessageType",
+ "Character",
+ "TraitorMessageType",
+ "ChatMessageType",
+ "CauseOfDeathType",
+ "CreateVector2",
+ "Item",
+ "ChatMessage",
+ "AfflictionPrefab",
+ "Gap",
+ "File",
+ "Networking",
+ "printNoLog",
+ "Client",
+ "SERVER",
+ "setmodulepaths",
+ "Type",
+ "BindingFlags",
+ "UserData",
+ "LuaUserData",
+ "CLIENT"
+ ]
+}
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua b/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua
new file mode 100644
index 000000000..acd20433e
--- /dev/null
+++ b/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua
@@ -0,0 +1,56 @@
+local defaultLib = {}
+
+require("DefaultRegister")
+
+local CreateStatic = function (typeName)
+ return LuaUserData.CreateStatic("Barotrauma." .. typeName)
+end
+
+defaultLib["WayPoint"] = CreateStatic("WayPoint")
+defaultLib["SpawnType"] = CreateStatic("SpawnType")
+defaultLib["ChatMessageType"] = CreateStatic("Networking.ChatMessageType")
+defaultLib["ServerLog_MessageType"] = CreateStatic("Networking.ServerLog+MessageType")
+defaultLib["ServerLogMessageType"] = CreateStatic("Networking.ServerLog+MessageType")
+defaultLib["Submarine"] = CreateStatic("Submarine")
+defaultLib["Client"] = CreateStatic("Networking.Client")
+defaultLib["Character"] = CreateStatic("Character")
+defaultLib["CharacterInfo"] = CreateStatic("CharacterInfo")
+defaultLib["Item"] = CreateStatic("Item")
+defaultLib["ItemPrefab"] = CreateStatic("ItemPrefab")
+defaultLib["Level"] = CreateStatic("Level")
+defaultLib["PositionType"] = CreateStatic("Level+PositionType")
+defaultLib["JobPrefab"] = CreateStatic("JobPrefab")
+defaultLib["TraitorMessageType"] = CreateStatic("Networking.TraitorMessageType")
+defaultLib["CauseOfDeathType"] = CreateStatic("CauseOfDeathType")
+defaultLib["AfflictionPrefab"] = CreateStatic("AfflictionPrefab")
+defaultLib["CharacterTeamType"] = CreateStatic("CharacterTeamType")
+defaultLib["Vector2"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Vector2")
+defaultLib["Vector3"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Vector3")
+defaultLib["Vector4"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Vector4")
+defaultLib["Color"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Color")
+defaultLib["Point"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Point")
+defaultLib["ChatMessage"] = CreateStatic("Networking.ChatMessage")
+defaultLib["Hull"] = CreateStatic("Hull")
+defaultLib["InvSlotType"] = CreateStatic("InvSlotType")
+defaultLib["Gap"] = CreateStatic("Gap")
+defaultLib["ContentPackage"] = CreateStatic("ContentPackage")
+defaultLib["ClientPermissions"] = CreateStatic("Networking.ClientPermissions")
+defaultLib["Signal"] = CreateStatic("Items.Components.Signal")
+defaultLib["DeliveryMethod"] = CreateStatic("Networking.DeliveryMethod")
+defaultLib["ClientPacketHeader"] = CreateStatic("Networking.ClientPacketHeader")
+defaultLib["ServerPacketHeader"] = CreateStatic("Networking.ServerPacketHeader")
+defaultLib["RandSync"] = CreateStatic("Rand+RandSync")
+defaultLib["SubmarineInfo"] = CreateStatic("SubmarineInfo")
+defaultLib["Rectangle"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Rectangle")
+defaultLib["Entity"] = CreateStatic("Entity")
+defaultLib["Physics"] = CreateStatic("Physics")
+
+if SERVER then
+
+elseif CLIENT then
+ defaultLib["Sprite"] = CreateStatic("Sprite")
+ defaultLib["Keys"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Input.Keys")
+ defaultLib["PlayerInput"] = CreateStatic("PlayerInput")
+end
+
+return defaultLib
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaShared/Lua/DefaultRegister.lua b/Barotrauma/BarotraumaShared/Lua/DefaultRegister.lua
new file mode 100644
index 000000000..887a1ba01
--- /dev/null
+++ b/Barotrauma/BarotraumaShared/Lua/DefaultRegister.lua
@@ -0,0 +1,157 @@
+local function RegisterBarotrauma(typeName)
+ return LuaUserData.RegisterType("Barotrauma." .. typeName)
+end
+
+local AddCallMetaMember = LuaUserData.AddCallMetaMember
+
+RegisterBarotrauma("CauseOfDeathType")
+RegisterBarotrauma("Level+InterestingPosition")
+RegisterBarotrauma("Level+PositionType")
+RegisterBarotrauma("Networking.TraitorMessageType")
+RegisterBarotrauma("SpawnType")
+RegisterBarotrauma("Networking.ChatMessageType")
+RegisterBarotrauma("InputType")
+
+RegisterBarotrauma("Job")
+RegisterBarotrauma("JobPrefab")
+RegisterBarotrauma("Level")
+RegisterBarotrauma("Items.Components.Steering")
+RegisterBarotrauma("Networking.ServerLog+MessageType")
+RegisterBarotrauma("WayPoint")
+RegisterBarotrauma("Character")
+RegisterBarotrauma("Item")
+RegisterBarotrauma("Submarine")
+RegisterBarotrauma("Networking.Client")
+RegisterBarotrauma("AfflictionPrefab")
+RegisterBarotrauma("Affliction")
+RegisterBarotrauma("CharacterHealth")
+RegisterBarotrauma("AnimController")
+RegisterBarotrauma("Limb")
+RegisterBarotrauma("Ragdoll")
+RegisterBarotrauma("Networking.ChatMessage")
+RegisterBarotrauma("CharacterHealth+LimbHealth")
+RegisterBarotrauma("AttackResult")
+RegisterBarotrauma("Entity")
+RegisterBarotrauma("EntitySpawner")
+RegisterBarotrauma("MapEntity")
+RegisterBarotrauma("MapEntityPrefab")
+RegisterBarotrauma("CauseOfDeath")
+RegisterBarotrauma("CharacterTeamType")
+RegisterBarotrauma("Items.Components.Connection")
+RegisterBarotrauma("CharacterInventory")
+RegisterBarotrauma("Hull")
+RegisterBarotrauma("Gap")
+RegisterBarotrauma("PhysicsBody")
+RegisterBarotrauma("InvSlotType")
+RegisterBarotrauma("ItemPrefab")
+RegisterBarotrauma("SerializableProperty")
+RegisterBarotrauma("StatusEffect")
+RegisterBarotrauma("FireSource")
+RegisterBarotrauma("ContentPackage")
+RegisterBarotrauma("SubmarineBody")
+RegisterBarotrauma("Explosion")
+RegisterBarotrauma("Networking.ServerSettings")
+RegisterBarotrauma("Inventory")
+RegisterBarotrauma("ItemInventory")
+
+RegisterBarotrauma("Items.Components.Fabricator")
+RegisterBarotrauma("Items.Components.ItemComponent")
+RegisterBarotrauma("Items.Components.WifiComponent")
+RegisterBarotrauma("Items.Components.LightComponent")
+RegisterBarotrauma("Items.Components.Holdable")
+RegisterBarotrauma("Items.Components.CustomInterface")
+RegisterBarotrauma("Items.Components.CustomInterface+CustomInterfaceElement")
+RegisterBarotrauma("Items.Components.ItemContainer")
+RegisterBarotrauma("Items.Components.PowerContainer")
+RegisterBarotrauma("Items.Components.Pickable")
+RegisterBarotrauma("Items.Components.Reactor")
+RegisterBarotrauma("Items.Components.RelayComponent")
+RegisterBarotrauma("Items.Components.MemoryComponent")
+RegisterBarotrauma("Items.Components.Engine")
+
+RegisterBarotrauma("AIController")
+RegisterBarotrauma("EnemyAIController")
+RegisterBarotrauma("HumanAIController")
+RegisterBarotrauma("AICharacter")
+RegisterBarotrauma("AITarget")
+RegisterBarotrauma("AITargetMemory")
+
+RegisterBarotrauma("TalentPrefab")
+RegisterBarotrauma("TalentOption")
+RegisterBarotrauma("TalentSubTree")
+RegisterBarotrauma("TalentTree")
+RegisterBarotrauma("CharacterTalent")
+
+RegisterBarotrauma("Screen")
+RegisterBarotrauma("GameScreen")
+RegisterBarotrauma("GameSession")
+RegisterBarotrauma("CampaignMode")
+
+local descriptor = RegisterBarotrauma("NetLobbyScreen")
+LuaUserData.MakeFieldAccessible(descriptor, "subs")
+
+RegisterBarotrauma("Networking.IWriteMessage")
+RegisterBarotrauma("Networking.IReadMessage")
+RegisterBarotrauma("Networking.ServerPacketHeader")
+RegisterBarotrauma("Networking.ClientPacketHeader")
+RegisterBarotrauma("Networking.DeliveryMethod")
+RegisterBarotrauma("Rand+RandSync")
+RegisterBarotrauma("Skill")
+RegisterBarotrauma("SkillPrefab")
+RegisterBarotrauma("TraitorMissionPrefab")
+RegisterBarotrauma("TraitorMissionResult")
+
+LuaUserData.RegisterType("FarseerPhysics.Dynamics.World")
+LuaUserData.RegisterType("FarseerPhysics.Dynamics.Fixture")
+RegisterBarotrauma("Physics")
+
+RegisterBarotrauma("Camera")
+RegisterBarotrauma("InputType")
+RegisterBarotrauma("Key")
+
+AddCallMetaMember(RegisterBarotrauma("CharacterInfo"))
+AddCallMetaMember(RegisterBarotrauma("Items.Components.Signal"))
+AddCallMetaMember(RegisterBarotrauma("SubmarineInfo"))
+
+AddCallMetaMember(LuaUserData.RegisterType("Microsoft.Xna.Framework.Vector2"))
+AddCallMetaMember(LuaUserData.RegisterType("Microsoft.Xna.Framework.Vector3"))
+AddCallMetaMember(LuaUserData.RegisterType("Microsoft.Xna.Framework.Vector4"))
+AddCallMetaMember(LuaUserData.RegisterType("Microsoft.Xna.Framework.Color"))
+AddCallMetaMember(LuaUserData.RegisterType("Microsoft.Xna.Framework.Point"))
+AddCallMetaMember(LuaUserData.RegisterType("Microsoft.Xna.Framework.Rectangle"))
+
+if SERVER then
+
+RegisterBarotrauma("Traitor")
+RegisterBarotrauma("Traitor+TraitorMission")
+
+elseif CLIENT then
+
+RegisterBarotrauma("LuaSetup+LuaGUI")
+RegisterBarotrauma("ChatBox")
+RegisterBarotrauma("GUICanvas")
+RegisterBarotrauma("Anchor")
+RegisterBarotrauma("Alignment")
+RegisterBarotrauma("Pivot")
+RegisterBarotrauma("Key")
+RegisterBarotrauma("PlayerInput")
+
+LuaUserData.RegisterType("Microsoft.Xna.Framework.Graphics.Texture2D")
+LuaUserData.RegisterType("EventInput.KeyEventArgs")
+LuaUserData.RegisterType("Microsoft.Xna.Framework.Input.Keys")
+
+AddCallMetaMember(RegisterBarotrauma("Sprite"))
+AddCallMetaMember(RegisterBarotrauma("GUILayoutGroup"))
+AddCallMetaMember(RegisterBarotrauma("GUITextBox"))
+AddCallMetaMember(RegisterBarotrauma("GUITextBlock"))
+AddCallMetaMember(RegisterBarotrauma("GUIButton"))
+AddCallMetaMember(RegisterBarotrauma("RectTransform"))
+AddCallMetaMember(RegisterBarotrauma("GUIFrame"))
+AddCallMetaMember(RegisterBarotrauma("GUITickBox"))
+AddCallMetaMember(RegisterBarotrauma("GUICustomComponent"))
+AddCallMetaMember(RegisterBarotrauma("GUIImage"))
+AddCallMetaMember(RegisterBarotrauma("GUIListBox"))
+AddCallMetaMember(RegisterBarotrauma("GUIScrollBar"))
+AddCallMetaMember(RegisterBarotrauma("GUIDropDown"))
+
+end
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaShared/Lua/MoonsharpSetup.lua b/Barotrauma/BarotraumaShared/Lua/LuaSetup.lua
similarity index 89%
rename from Barotrauma/BarotraumaShared/Lua/MoonsharpSetup.lua
rename to Barotrauma/BarotraumaShared/Lua/LuaSetup.lua
index 327974002..cd83b391e 100644
--- a/Barotrauma/BarotraumaShared/Lua/MoonsharpSetup.lua
+++ b/Barotrauma/BarotraumaShared/Lua/LuaSetup.lua
@@ -1,4 +1,14 @@
+-- Config
+
local runDisabledMods = false
+local modulePaths = {"Lua/?.lua"}
+setmodulepaths(modulePaths)
+
+local defaultLib = require("DefaultLib")
+
+for key, value in pairs(defaultLib) do
+ _G[key] = value
+end
if SERVER and Game.IsDedicated then
runDisabledMods = true
@@ -30,8 +40,6 @@ local function runFolder(folder)
end
end
-local modulePaths = {}
-
if not runDisabledMods then
for _, package in pairs(enabledPackages) do
diff --git a/Barotrauma/BarotraumaShared/Lua/NluaSetup.lua b/Barotrauma/BarotraumaShared/Lua/NluaSetup.lua
deleted file mode 100644
index e69de29bb..000000000
diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs
index 6e88b11d6..3ea2b743e 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs
@@ -11,6 +11,10 @@ using System.Net;
using System.Linq;
using System.Xml.Linq;
using FarseerPhysics.Dynamics;
+using System.Reflection;
+using HarmonyLib;
+using MoonSharp.Interpreter.Interop;
+using System.Diagnostics;
namespace Barotrauma
{
@@ -32,7 +36,82 @@ namespace Barotrauma
return new Vector4(x, y, z, w);
}
- private partial class LuaPlayer
+ partial class LuaUserData
+ {
+ public static Type GetType(string typeName)
+ {
+ var type = Type.GetType(typeName);
+ if (type != null) return type;
+ foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
+ {
+ type = a.GetType(typeName);
+ if (type != null)
+ return type;
+ }
+ return null;
+ }
+
+ public static IUserDataDescriptor RegisterType(string typeName)
+ {
+ Type type = GetType(typeName);
+
+ MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.RegisterType), new Type[2] { typeof(InteropAccessMode), typeof(string) });
+ MethodInfo generic = method.MakeGenericMethod(type);
+ return (IUserDataDescriptor)generic.Invoke(null, new object[] { null, null });
+ }
+
+ public static object CreateStatic(string typeName)
+ {
+ Type type = GetType(typeName);
+
+ MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
+ MethodInfo generic = method.MakeGenericMethod(type);
+ return generic.Invoke(null, null);
+ }
+
+ public static void AddCallMetaMember(IUserDataDescriptor IUDD)
+ {
+ var descriptor = (StandardUserDataDescriptor)IUDD;
+ descriptor.RemoveMetaMember("__call");
+ descriptor.AddMetaMember("__call", new ObjectCallbackMemberDescriptor("__call", LuaSetup.luaSetup.HandleCall));
+ }
+
+ public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string methodName)
+ {
+ var descriptor = (StandardUserDataDescriptor)IUUD;
+ var field = IUUD.Type.GetField(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
+ descriptor.RemoveMember(methodName);
+ descriptor.AddMember(methodName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
+ }
+
+ public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName)
+ {
+ var descriptor = (StandardUserDataDescriptor)IUUD;
+ var method = IUUD.Type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
+ descriptor.RemoveMember(methodName);
+ descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
+ }
+
+ public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
+ {
+ var descriptor = (StandardUserDataDescriptor)IUUD;
+ descriptor.RemoveMember(methodName);
+ descriptor.AddMember(methodName, new ObjectCallbackMemberDescriptor(methodName, (object arg1, ScriptExecutionContext arg2, CallbackArguments arg3) =>
+ {
+ if (luaSetup != null)
+ return luaSetup.CallFunction(function, arg3.GetArray());
+ return null;
+ }));
+ }
+
+ public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
+ {
+ var descriptor = (StandardUserDataDescriptor)IUUD;
+ descriptor.RemoveMember(memberName);
+ }
+ }
+
+ public partial class LuaPlayer
{
}
@@ -322,8 +401,10 @@ namespace Barotrauma
}
- private partial class LuaTimer
+ public partial class LuaTimer
{
+ public static long LastUpdateTime = 0;
+
public LuaSetup env;
public LuaTimer(LuaSetup e)
@@ -331,12 +412,27 @@ namespace Barotrauma
env = e;
}
+ public static double Time
+ {
+ get
+ {
+ return GetTime();
+ }
+ }
+
public static double GetTime()
{
return Timing.TotalTime;
}
+ public static float GetUsageMemory()
+ {
+ Process proc = Process.GetCurrentProcess();
+ float memory = MathF.Round(proc.PrivateMemorySize64 / (1024 * 1024), 2);
+ proc.Dispose();
+ return memory;
+ }
}
private partial class LuaRandom
@@ -592,6 +688,7 @@ namespace Barotrauma
public LuaHook(LuaSetup e)
{
env = e;
+ methodNameToHookName = new Dictionary();
}
public class HookFunction
@@ -608,7 +705,60 @@ namespace Barotrauma
}
}
- public Dictionary> hookFunctions = new Dictionary>();
+ private Dictionary> hookFunctions = new Dictionary>();
+
+ private static Dictionary methodNameToHookName;
+
+ public enum HookMethodType
+ {
+ Before, After
+ }
+
+ static void HookLuaPatchPrefix(MethodBase __originalMethod)
+ {
+ luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name]);
+ }
+
+ static void HookLuaPatchPostfix(MethodBase __originalMethod)
+ {
+ luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name]);
+ }
+
+ // not very useful until i find a way to use the transpiler to inject arguments into the call
+
+ public void HookMethod(string className, string methodName, string hookName, HookMethodType hookMethodType = HookMethodType.Before)
+ {
+ var classType = Type.GetType(className);
+ var methodInfos = classType.GetMethods();
+ HarmonyMethod harmonyMethod = new HarmonyMethod();
+
+ if (hookMethodType == HookMethodType.Before)
+ {
+ harmonyMethod = new HarmonyMethod(GetType().GetMethod("HookLuaPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static));
+ }
+ else if (hookMethodType == HookMethodType.After)
+ {
+ harmonyMethod = new HarmonyMethod(GetType().GetMethod("HookLuaPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static));
+ }
+
+ var foundAny = false;
+
+ foreach (var methodInfo in methodInfos)
+ {
+ if(methodInfo.Name == methodName)
+ {
+ if (hookMethodType == HookMethodType.Before)
+ env.harmony.Patch(methodInfo, harmonyMethod);
+ else if (hookMethodType == HookMethodType.After)
+ env.harmony.Patch(methodInfo, postfix: harmonyMethod);
+
+ foundAny = true;
+ }
+ }
+
+ if(foundAny)
+ methodNameToHookName.Add(methodName, hookName);
+ }
public void Add(string name, string hookName, object function)
{
@@ -632,7 +782,7 @@ namespace Barotrauma
hookFunctions[name].Remove(hookName);
}
- public object Call(string name, object[] args)
+ public object Call(string name, params object[] args)
{
if (env == null) return null;
if (name == null) return null;
@@ -653,12 +803,16 @@ namespace Barotrauma
if (!result.IsNil())
lastResult = result;
}
- //else if (hf.function is NLua.LuaFunction luaFunction)
- // lastResult = luaFunction.Call(args);
}
catch (Exception e)
{
- env.HandleLuaException(e);
+ StringBuilder argsSb = new StringBuilder();
+ foreach(var arg in args)
+ {
+ argsSb.Append(arg + " ");
+ }
+
+ env.HandleLuaException(e, $"Error in Hook '{name}'->'{hf.hookName}', with args '{argsSb}'");
}
}
diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs
index 6d12d62a6..35afb201b 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs
@@ -13,6 +13,7 @@ using MoonSharp.Interpreter.Interop;
using System.Reflection;
using FarseerPhysics.Dynamics;
using System.IO.Compression;
+using HarmonyLib;
#if CLIENT
using Microsoft.Xna.Framework.Graphics;
@@ -31,11 +32,15 @@ namespace Barotrauma
public LuaHook hook;
public LuaGame game;
public LuaNetworking networking;
+ public Harmony harmony;
public LuaScriptLoader luaScriptLoader;
- public void HandleLuaException(Exception ex)
+ public void HandleLuaException(Exception ex, string extra = "")
{
+ if (!string.IsNullOrWhiteSpace(extra))
+ PrintMessage(extra);
+
if (ex is InterpreterException)
{
if (((InterpreterException)ex).DecoratedMessage == null)
@@ -197,8 +202,9 @@ namespace Barotrauma
}
// messy solution
- private object HandleCall(object arg1, ScriptExecutionContext arg2, CallbackArguments arg3)
+ public object HandleCall(object arg1, ScriptExecutionContext arg2, CallbackArguments arg3)
{
+
var what = arg3.RawGet(0, true);
var code = "return " + what.UserData.Descriptor.Type.Name + ".__new(";
@@ -230,12 +236,6 @@ namespace Barotrauma
return null;
}
- private void AddCallMetaMember(IUserDataDescriptor IUDD)
- {
- var descriptor = (StandardUserDataDescriptor)IUDD;
- descriptor.RemoveMetaMember("__call");
- descriptor.AddMetaMember("__call", new ObjectCallbackMemberDescriptor("__call", HandleCall));
- }
#if SERVER
public static void InstallClientSideLua()
@@ -301,6 +301,17 @@ namespace Barotrauma
LuaCustomConverters.RegisterAll();
+ lua = new Script(CoreModules.Preset_SoftSandbox);
+ lua.Options.DebugPrint = PrintMessage;
+ lua.Options.ScriptLoader = luaScriptLoader;
+
+ harmony = new Harmony("com.LuaForBarotrauma");
+ harmony.UnpatchAll();
+
+ hook = new LuaHook(this);
+ game = new LuaGame(this);
+ networking = new LuaNetworking(this);
+
UserData.RegisterType();
UserData.RegisterType();
UserData.RegisterType();
@@ -308,83 +319,8 @@ namespace Barotrauma
UserData.RegisterType();
UserData.RegisterType();
UserData.RegisterType();
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType- ();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType>();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
+ UserData.RegisterType();
+ UserData.RegisterType();
UserData.RegisterType>();
UserData.RegisterType>();
@@ -392,90 +328,10 @@ namespace Barotrauma
UserData.RegisterType>();
UserData.RegisterType>();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
+ UserData.RegisterType>();
- {
- var descriptor = (StandardUserDataDescriptor)UserData.RegisterType();
- var type = typeof(NetLobbyScreen);
- var field = type.GetField("subs", BindingFlags.NonPublic | BindingFlags.Instance);
- descriptor.RemoveMember("subs");
- descriptor.AddMember("subs", new FieldMemberDescriptor(field, InteropAccessMode.Default));
- }
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType(typeof(Physics));
-
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
-
-#if SERVER
- UserData.RegisterType();
- UserData.RegisterType();
-#elif CLIENT
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
-
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
- AddCallMetaMember(UserData.RegisterType());
-#endif
- lua = new Script(CoreModules.Preset_SoftSandbox);
-
- lua.Options.DebugPrint = PrintMessage;
-
- lua.Options.ScriptLoader = luaScriptLoader;
-
- hook = new LuaHook(this);
- game = new LuaGame(this);
- networking = new LuaNetworking(this);
+ lua.Globals["setmodulepaths"] = (Action)SetModulePaths;
lua.Globals["TestFunction"] = (Func)TestFunction;
@@ -487,9 +343,8 @@ namespace Barotrauma
lua.Globals["dostring"] = (Func)DoString;
lua.Globals["load"] = (Func)LoadString;
-
- lua.Globals["setmodulepaths"] = (Action)SetModulePaths;
-
+
+ lua.Globals["LuaUserData"] = UserData.CreateStatic();
lua.Globals["Player"] = new LuaPlayer();
lua.Globals["Game"] = game;
lua.Globals["Hook"] = hook;
@@ -497,56 +352,17 @@ namespace Barotrauma
lua.Globals["Timer"] = new LuaTimer(this);
lua.Globals["File"] = UserData.CreateStatic();
lua.Globals["Networking"] = networking;
- lua.Globals["WayPoint"] = UserData.CreateStatic();
- lua.Globals["SpawnType"] = UserData.CreateStatic();
- lua.Globals["ChatMessageType"] = UserData.CreateStatic();
- lua.Globals["ServerLog_MessageType"] = UserData.CreateStatic();
- lua.Globals["Submarine"] = UserData.CreateStatic();
- lua.Globals["Client"] = UserData.CreateStatic();
- lua.Globals["Character"] = UserData.CreateStatic();
- lua.Globals["CharacterInfo"] = UserData.CreateStatic();
- lua.Globals["Item"] = UserData.CreateStatic
- ();
- lua.Globals["ItemPrefab"] = UserData.CreateStatic();
- lua.Globals["Level"] = UserData.CreateStatic();
- lua.Globals["PositionType"] = UserData.CreateStatic();
- lua.Globals["JobPrefab"] = UserData.CreateStatic();
- lua.Globals["TraitorMessageType"] = UserData.CreateStatic();
- lua.Globals["CauseOfDeathType"] = UserData.CreateStatic();
- lua.Globals["AfflictionPrefab"] = UserData.CreateStatic();
- lua.Globals["CharacterTeamType"] = UserData.CreateStatic();
- lua.Globals["Vector2"] = UserData.CreateStatic();
- lua.Globals["Vector3"] = UserData.CreateStatic();
- lua.Globals["Vector4"] = UserData.CreateStatic();
- lua.Globals["Color"] = UserData.CreateStatic();
- lua.Globals["Point"] = UserData.CreateStatic();
- lua.Globals["ChatMessage"] = UserData.CreateStatic();
- lua.Globals["Hull"] = UserData.CreateStatic();
- lua.Globals["InvSlotType"] = UserData.CreateStatic();
- lua.Globals["Gap"] = UserData.CreateStatic();
- lua.Globals["ContentPackage"] = UserData.CreateStatic();
- lua.Globals["ClientPermissions"] = UserData.CreateStatic();
- lua.Globals["Signal"] = UserData.CreateStatic();
- lua.Globals["DeliveryMethod"] = UserData.CreateStatic();
- lua.Globals["ClientPacketHeader"] = UserData.CreateStatic();
- lua.Globals["ServerPacketHeader"] = UserData.CreateStatic();
- lua.Globals["RandSync"] = UserData.CreateStatic();
- lua.Globals["SubmarineInfo"] = UserData.CreateStatic();
- lua.Globals["Rectangle"] = UserData.CreateStatic();
- lua.Globals["Entity"] = UserData.CreateStatic();
- lua.Globals["Physics"] = UserData.CreateStatic(typeof(Physics));
+
+ // obsolete
+ lua.Globals["CreateVector2"] = (Func)CreateVector2;
+ lua.Globals["CreateVector3"] = (Func)CreateVector3;
+ lua.Globals["CreateVector4"] = (Func)CreateVector4;
#if SERVER
#elif CLIENT
lua.Globals["GUI"] = new LuaGUI(this);
- lua.Globals["Sprite"] = UserData.CreateStatic();
- lua.Globals["Keys"] = UserData.CreateStatic();
- lua.Globals["PlayerInput"] = UserData.CreateStatic();
#endif
- // obsolete
- lua.Globals["CreateVector2"] = (Func)CreateVector2;
- lua.Globals["CreateVector3"] = (Func)CreateVector3;
- lua.Globals["CreateVector4"] = (Func)CreateVector4;
bool isServer = true;
@@ -561,13 +377,13 @@ namespace Barotrauma
// LuaDocs.GenerateDocs(typeof(EntitySpawner));
- if (File.Exists("Lua/MoonsharpSetup.lua")) // try the default loader
- DoFile("Lua/MoonsharpSetup.lua");
- else if (File.Exists("Mods/LuaForBarotrauma/Lua/MoonsharpSetup.lua")) // in case its the workshop version
- DoFile("Mods/LuaForBarotrauma/Lua/MoonsharpSetup.lua");
+ if (File.Exists("Lua/LuaSetup.lua")) // try the default loader
+ DoFile("Lua/LuaSetup.lua");
+ else if (File.Exists("Mods/LuaForBarotrauma/Lua/LuaSetup.lua")) // in case its the workshop version
+ DoFile("Mods/LuaForBarotrauma/Lua/LuaSetup.lua");
else // fallback to c# script loading
{
- PrintMessage("Lua/MoonSharp.lua not found, loading Mods directly, things can break!");
+ PrintMessage("Lua/LuaSetup.lua not found, loading Mods directly, things can break!");
List modulePaths = new List();