diff --git a/Barotrauma/BarotraumaClient/ClientSource/GameMain.cs b/Barotrauma/BarotraumaClient/ClientSource/GameMain.cs index 005ae4e48..d03924def 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GameMain.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GameMain.cs @@ -923,7 +923,7 @@ namespace Barotrauma SoundManager?.Update(); GameMain.LuaCs.Update(); - GameMain.LuaCs.HookBase.Call("think"); + GameMain.LuaCs.Hook.Call("think"); Timing.Accumulator -= Timing.Step; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs index 059f2dafe..3c1128032 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs @@ -2830,9 +2830,8 @@ namespace Barotrauma.Networking public override void AddChatMessage(ChatMessage message) { - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("chatMessage", message.Text, message.SenderClient, message.Type, message)); - - if (should.Bool()) return; + var should = GameMain.LuaCs.Hook.Call("chatMessage", message.Text, message.SenderClient, message.Type, message); + if (should != null && should.Value) return; base.AddChatMessage(message); diff --git a/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs b/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs index ec3d4b665..c84e3b896 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs @@ -562,7 +562,7 @@ namespace Barotrauma allowInput = true; } - GameMain.LuaCs.HookBase.Call("keyUpdate", deltaTime); + GameMain.LuaCs.Hook.Call("keyUpdate", deltaTime); oldMouseState = mouseState; mouseState = latestMouseState; diff --git a/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs b/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs index efd219c94..204c853ee 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs @@ -25,7 +25,7 @@ namespace Barotrauma GameServer.Log(GameServer.CharacterLogName(this) + " has died (Cause of death: " + causeOfDeath + ")", ServerLog.MessageType.Attack); } } - GameMain.LuaCs.HookBase.Call("characterDeath", this,causeOfDeathAffliction); + GameMain.LuaCs.Hook.Call("characterDeath", this,causeOfDeathAffliction); if (HasAbilityFlag(AbilityFlags.RetainExperienceForNewCharacter)) { diff --git a/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs b/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs index fe8576eff..9201fe9aa 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs @@ -348,9 +348,9 @@ namespace Barotrauma CoroutineManager.Update((float)Timing.Step, (float)Timing.Step); GameMain.LuaCs.Update(); - GameMain.LuaCs.HookBase.Call("think", new object[] { }); + GameMain.LuaCs.Hook.Call("think", new object[] { }); performanceCounterTimer.Stop(); - LuaTimer.LastUpdateTime = performanceCounterTimer.ElapsedMilliseconds; + LuaCsTimer.LastUpdateTime = performanceCounterTimer.ElapsedMilliseconds; performanceCounterTimer.Reset(); Timing.Accumulator -= Timing.Step; diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs index ee6ce4b71..e580bb693 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs @@ -133,9 +133,9 @@ namespace Barotrauma.Networking return; } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("chatMessage", txt, c, type)); + var should = GameMain.LuaCs.Hook.Call("chatMessage", txt, c, type); - if (should.Bool()) + if (should != null && should.Value) { return; } diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs index f1f4d19a7..bbc42cd10 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs @@ -290,7 +290,7 @@ namespace Barotrauma.Networking SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient); } - GameMain.LuaCs.HookBase.Call("clientConnected", newClient); + GameMain.LuaCs.Hook.Call("clientConnected", newClient); SendChatMessage($"ServerMessage.JoinedServer~[client]={clName}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined); @@ -1804,7 +1804,7 @@ namespace Barotrauma.Networking outmsg.Write((byte)ServerNetObject.CLIENT_LIST); outmsg.Write(LastClientListUpdateID); - GameMain.LuaCs.HookBase.Call("writeClientList", c, outmsg); + GameMain.LuaCs.Hook.Call("writeClientList", c, outmsg); outmsg.Write((byte)connectedClients.Count); foreach (Client client in connectedClients) @@ -2251,7 +2251,7 @@ namespace Barotrauma.Networking AssignJobs(teamClients); - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("jobsAssigned")); + GameMain.LuaCs.Hook.Call("jobsAssigned"); List characterInfos = new List(); foreach (Client client in teamClients) @@ -2455,7 +2455,7 @@ namespace Barotrauma.Networking roundStartTime = DateTime.Now; - GameMain.LuaCs.HookBase.Call("roundStart"); + GameMain.LuaCs.Hook.Call("roundStart"); startGameCoroutine = null; yield return CoroutineStatus.Success; @@ -2586,7 +2586,7 @@ namespace Barotrauma.Networking Log("Ending the round...", ServerLog.MessageType.ServerMessage); } - GameMain.LuaCs.HookBase.Call("roundEnd"); + GameMain.LuaCs.Hook.Call("roundEnd"); string endMessage = TextManager.FormatServerMessage("RoundSummaryRoundHasEnded"); @@ -2697,12 +2697,12 @@ namespace Barotrauma.Networking newName = Client.SanitizeName(newName); if (newName == c.Name && newJob == c.PreferredJob && newTeam == c.PreferredTeam) { return false; } - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("tryChangeClientName", c, newName, newJob, newTeam)); + var result = GameMain.LuaCs.Hook.Call("tryChangeClientName", c, newName, newJob, newTeam); - if (!result.IsNull()) + if (result != null) { LastClientListUpdateID++; - return result.Bool(); + return result.Value; } c.PreferredJob = newJob; @@ -2892,7 +2892,7 @@ namespace Barotrauma.Networking { if (client == null) return; - GameMain.LuaCs.HookBase.Call("clientDisconnected", client); + GameMain.LuaCs.Hook.Call("clientDisconnected", client); if (gameStarted && client.Character != null) { @@ -3142,9 +3142,9 @@ namespace Barotrauma.Networking var hookChatMsg = ChatMessage.Create(senderName, message, (ChatMessageType)type, senderCharacter, senderClient, changeType); - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("modifyChatMessage", hookChatMsg, senderRadio)); + var should = GameMain.LuaCs.Hook.Call("modifyChatMessage", hookChatMsg, senderRadio); - if (should.Bool()) + if (should != null && should.Value) return; @@ -3874,7 +3874,7 @@ namespace Barotrauma.Networking { if (GameMain.Server == null || !GameMain.Server.ServerSettings.SaveServerLogs) { return; } - GameMain.LuaCs?.HookBase?.Call("serverLog", line, messageType); + GameMain.LuaCs?.Hook?.Call("serverLog", line, messageType); GameMain.Server.ServerSettings.ServerLog.WriteLine(line, messageType); diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/LidgrenServerPeer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/LidgrenServerPeer.cs index bded9b025..07c409d06 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/LidgrenServerPeer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/LidgrenServerPeer.cs @@ -184,9 +184,9 @@ namespace Barotrauma.Networking var skipDeny = false; { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("lidgren.handleConnection", inc)); - if (!result.IsNull()) { - if (result.Bool()) skipDeny = true; + var result = GameMain.LuaCs.Hook.Call("lidgren.handleConnection", inc); + if (result != null) { + if (result.Value) skipDeny = true; else return; } } diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/ServerPeer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/ServerPeer.cs index 4bd6632c7..93f931061 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/ServerPeer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/Primitives/Peers/Server/ServerPeer.cs @@ -206,18 +206,16 @@ namespace Barotrauma.Networking protected void UpdatePendingClient(PendingClient pendingClient) { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("handlePendingClient", pendingClient)); + var skipRemove = false; + var result = GameMain.LuaCs.Hook.Call("handlePendingClient", pendingClient); - if (result.Bool()) - goto ignore; + if (result != null) skipRemove = result.Value; - if (connectedClients.Count >= serverSettings.MaxPlayers) + if (!skipRemove && connectedClients.Count >= serverSettings.MaxPlayers) { RemovePendingClient(pendingClient, DisconnectReason.ServerFull, ""); } - ignore: - if (IsPendingClientBanned(pendingClient, out string banReason)) { RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason); diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/Voip/VoipServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/Voip/VoipServer.cs index a8a16e6be..3e3474ab3 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/Voip/VoipServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/Voip/VoipServer.cs @@ -94,19 +94,19 @@ namespace Barotrauma.Networking ChatMessage.CanUseRadio(sender.Character, out WifiComponent senderRadio) && ChatMessage.CanUseRadio(recipient.Character, out WifiComponent recipientRadio)) { - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("canUseVoiceRadio", new object[] { sender, recipient })); + var should = GameMain.LuaCs.Hook.Call("canUseVoiceRadio", new object[] { sender, recipient }); - if (!should.IsNull()) - return should.Bool(); + if (should != null) + return should.Value; if (recipientRadio.CanReceive(senderRadio)) { return true; } } - var should2 = new LuaResult(GameMain.LuaCs.HookBase.Call("changeLocalVoiceRange", new object[] { sender, recipient })); + var should2 = GameMain.LuaCs.Hook.Call("changeLocalVoiceRange", sender, recipient); float range = 1.0f; - if (!should2.IsNull()) - range = should2.Float(); + if (should2 != null) + range = should2.Value; //otherwise do a distance check diff --git a/Barotrauma/BarotraumaServer/ServerSource/Traitors/TraitorMission.cs b/Barotrauma/BarotraumaServer/ServerSource/Traitors/TraitorMission.cs index e5119eb24..38331b740 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Traitors/TraitorMission.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Traitors/TraitorMission.cs @@ -92,8 +92,8 @@ namespace Barotrauma var traitorCandidates = new List>(); foreach (Client c in server.ConnectedClients) { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("traitor.findTraitorCandidate", new object[] { c, team })); - if (result.Bool()) + var result = GameMain.LuaCs.Hook.Call("traitor.findTraitorCandidate", c, team); + if (result != null && result.Value) { traitorCandidates.Add(Tuple.Create(c, c.Character)); continue; @@ -234,7 +234,7 @@ namespace Barotrauma foreach (var traitor in Traitors.Values) { traitor.Greet(server, CodeWords, CodeResponse, message => pendingMessages[traitor].Add(message)); - GameMain.LuaCs.HookBase.Call("traitor.traitorAssigned", new object[] { traitor }); + GameMain.LuaCs.Hook.Call("traitor.traitorAssigned", new object[] { traitor }); } pendingMessages.ForEach(traitor => traitor.Value.ForEach(message => traitor.Key.SendChatMessage(message, Identifier))); pendingMessages.ForEach(traitor => traitor.Value.ForEach(message => traitor.Key.SendChatMessageBox(message, Identifier))); diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index 783f5c989..2483ee4bf 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -64,6 +64,8 @@ + + diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs index 9ce521ab5..d476ba3fb 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs @@ -80,9 +80,9 @@ namespace Barotrauma public void AddObjective(T objective) where T : AIObjective { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("AI.AddObjective", this, objective)); + var result = GameMain.LuaCs.Hook.Call("AI.AddObjective", this, objective); - if (result.Bool()) return; + if (result != null && result.Value) return; if (objective == null) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs index fb8857c70..9319ff911 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs @@ -1440,11 +1440,11 @@ namespace Barotrauma // -> the character should be revived if there are no major afflictions in addition to lack of oxygen target.Oxygen = Math.Max(target.Oxygen + 10.0f, 10.0f); - GameMain.LuaCs.HookBase.Call("human.CPRSuccess", this); + GameMain.LuaCs.Hook.Call("human.CPRSuccess", this); } else { - GameMain.LuaCs.HookBase.Call("human.CPRFailed", this); + GameMain.LuaCs.Hook.Call("human.CPRFailed", this); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs index 5a6b9560c..11636752a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs @@ -745,11 +745,11 @@ namespace Barotrauma float impactDamage = Math.Min((impact - ImpactTolerance) * ImpactDamageMultiplayer, character.MaxVitality * MaxImpactDamage); - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("changeFallDamage", new object[] { impactDamage, character, impactPos, velocity })); + var should = GameMain.LuaCs.Hook.Call("changeFallDamage", impactDamage, character, impactPos, velocity); - if (!should.IsNull()) + if (should != null) { - impactDamage = should.Float(); + impactDamage = should.Value; } character.LastDamageSource = null; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs index 5c39e15da..ac92e6789 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs @@ -1043,7 +1043,7 @@ namespace Barotrauma } #endif - GameMain.LuaCs.HookBase.Call("characterCreated", new object[] { newCharacter }); + GameMain.LuaCs.Hook.Call("characterCreated", new object[] { newCharacter }); return newCharacter; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs index 7f7af6897..77b380773 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs @@ -388,7 +388,7 @@ namespace Barotrauma AdditionStrength -= amount; } #if SERVER - GameMain.LuaCs.HookBase.Call("afflictionUpdate", new object[] { this, characterHealth, targetLimb, deltaTime }); + GameMain.LuaCs.Hook.Call("afflictionUpdate", new object[] { this, characterHealth, targetLimb, deltaTime }); #endif } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs index e5a1e7eeb..2ab56fc44 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs @@ -308,7 +308,7 @@ namespace Barotrauma if (client != null) { GameMain.Server.SetClientCharacter(client, husk); - GameMain.LuaCs.HookBase.Call("husk.clientControlHusk", new object[] { client, husk }); + GameMain.LuaCs.Hook.Call("husk.clientControlHusk", new object[] { client, husk }); } #else if (!character.IsRemotelyControlled && character == Character.Controlled) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs index 039be9c21..08faac3cc 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs @@ -541,9 +541,9 @@ namespace Barotrauma return; } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("character.applyDamage", new object[] { this, attackResult, hitLimb, allowStacking })); + var should = GameMain.LuaCs.Hook.Call("character.applyDamage", this, attackResult, hitLimb, allowStacking); - if (should.Bool()) + if (should != null && should.Value) return; foreach (Affliction newAffliction in attackResult.Afflictions) @@ -674,9 +674,9 @@ namespace Barotrauma } } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("character.applyAffliction", new object[] { this, limbHealth, newAffliction, allowStacking })); + var should = GameMain.LuaCs.Hook.Call("character.applyAffliction", this, limbHealth, newAffliction, allowStacking); - if (should.Bool()) + if (should != null && should.Value) return; Affliction existingAffliction = null; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Cs/ACsMod.cs b/Barotrauma/BarotraumaShared/SharedSource/Cs/ACsMod.cs index 4a3598f55..e6bc2c937 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Cs/ACsMod.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Cs/ACsMod.cs @@ -9,12 +9,6 @@ namespace Barotrauma private static List mods = new List(); public static List LoadedMods { get => mods; } - //public static ACsMod CreateInstance(Type type) - //{ - // if (!type.IsSubclassOf(typeof(ACsMod))) throw new Exception("Type argument is not the subclass of ACsMod."); - // return type.GetConstructor(new Type[] { }).Invoke(new object[] { }) as ACsMod; - //} - public bool IsDisposed { get; private set; } public ACsMod() diff --git a/Barotrauma/BarotraumaShared/SharedSource/Cs/CsHook.cs b/Barotrauma/BarotraumaShared/SharedSource/Cs/CsHook.cs deleted file mode 100644 index 9c01b0ef0..000000000 --- a/Barotrauma/BarotraumaShared/SharedSource/Cs/CsHook.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Reflection; - - -namespace Barotrauma -{ - - partial class LuaCsSetup - { - // CSharp wrapper for LuaCsHook - public class CsHook : LuaCsHookWrapper - { - public CsHook(LuaCsHook hook) : base(hook) { } - - public void HookMethod(string identifier, MethodInfo method, CsPatchDelegate hook, HookMethodType hookType = HookMethodType.Before, ACsMod owner = null) => - _hook.HookCsMethod(identifier, method, hook, hookType, owner); - - public void UnhookMethod(string identifier, MethodInfo method, HookMethodType hookType = HookMethodType.Before) => - _hook.RemovePatch(identifier, method, hookType); - - public void Add(string name, string hookName, CsHookDelegate hook, ACsMod owner = null) => - _hook.AddCsHook(name, hookName, hook, owner); - - } - } - -} \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptFilter.cs b/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptFilter.cs index 00aa08d9d..70245a727 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptFilter.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptFilter.cs @@ -1,10 +1,8 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Scripting; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Reflection.Metadata; @@ -28,7 +26,7 @@ namespace Barotrauma { }; private static string[] typessProhibited = new string[] { //"System.Reflection", - "System.IO.File", + "System.IO", }; public static bool IsTypeAllowed(string usingName) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptLoader.cs index 69fc30410..7c5fef1f9 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptLoader.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Cs/CsScriptLoader.cs @@ -48,22 +48,13 @@ namespace Barotrauma { var s = str.Replace("\\", "/"); - if (s.EndsWith(".cs")) - { - LuaCsSetup.PrintCsMessage(s); - scriptFiles.Add(s); - } + if (s.EndsWith(".cs") && LuaCsFile.IsPathAllowedCsException(s)) scriptFiles.Add(s); } try { if (scriptFiles.Count <= 0) return; - var mainFile = scriptFiles.Find(s => s.EndsWith("Main.cs")); - if (mainFile == null) throw new Exception("Mod folder has no Main.cs file"); - scriptFiles.Remove(mainFile); - scriptFiles.Add(mainFile); - // Check file content for prohibited stuff foreach (var file in scriptFiles) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs index 984f28a04..f56a45a5e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs @@ -526,7 +526,7 @@ namespace Barotrauma HintManager.OnRoundStarted(); - GameMain.LuaCs.HookBase.Call("roundStart"); + GameMain.LuaCs.Hook.Call("roundStart"); #endif } @@ -781,7 +781,7 @@ namespace Barotrauma RoundEnding = true; #if CLIENT - GameMain.LuaCs.HookBase.Call("roundEnd"); + GameMain.LuaCs.Hook.Call("roundEnd"); #endif //Clear the grids to allow for garbage collection Powered.Grids.Clear(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs index ec176e893..9b212e94d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs @@ -387,7 +387,7 @@ namespace Barotrauma.Items.Components Limb targetLimb = target.UserData as Limb; Character targetCharacter = targetLimb?.character ?? target.UserData as Character; - GameMain.LuaCs.HookBase.Call("meleeWeapon.handleImpact", this, target); + GameMain.LuaCs.Hook.Call("meleeWeapon.handleImpact", this, target); if (Attack != null) { Attack.SetUser(User); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Connection.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Connection.cs index ad2fb88ab..a83408696 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Connection.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Connection.cs @@ -325,8 +325,8 @@ namespace Barotrauma.Items.Components Connection connection = recipient; object[] obj = new object[] { signal, connection }; - GameMain.LuaCs.HookBase.Call("signalReceived", obj); - GameMain.LuaCs.HookBase.Call("signalReceived." + recipient.item.Prefab.Identifier, obj); + GameMain.LuaCs.Hook.Call("signalReceived", obj); + GameMain.LuaCs.Hook.Call("signalReceived." + recipient.item.Prefab.Identifier, obj); foreach (ItemComponent ic in recipient.item.Components) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs index 4abeebc88..74a2ebd46 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs @@ -205,9 +205,9 @@ namespace Barotrauma.Items.Components public void TransmitSignal(Signal signal, bool sentFromChat) { - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("wifiSignalTransmitted", new object[] { this, signal, sentFromChat })); + var should = GameMain.LuaCs.Hook.Call("wifiSignalTransmitted", this, signal, sentFromChat); - if (should.Bool()) + if (should != null && should.Value) return; if (sentFromChat) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs index ed2a7a75f..1d49ba47c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs @@ -540,9 +540,9 @@ namespace Barotrauma return; } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("inventoryPutItem", new object[] { this, item, user, i, removeItem })); + var should = GameMain.LuaCs.Hook.Call("inventoryPutItem", this, item, user, i, removeItem); - if (should.Bool()) + if (should != null && should.Value) return; if (Owner == null) { return; } @@ -648,10 +648,10 @@ namespace Barotrauma if (slots[index].Items.Any(it => !it.IsInteractable(user))) { return false; } if (!AllowSwappingContainedItems) { return false; } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("inventoryItemSwap", new object[] { this, item, user, index, swapWholeStack })); + var should = GameMain.LuaCs.Hook.Call("inventoryItemSwap", this, item, user, index, swapWholeStack); - if (!should.IsNull()) - return should.Bool(); + if (should != null) + return should.Value; //swap to InvSlotType.Any if possible Inventory otherInventory = item.ParentInventory; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs index bda8f340a..52fe5d778 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs @@ -999,7 +999,7 @@ namespace Barotrauma if (Components.Any(ic => ic is Wire) && Components.All(ic => ic is Wire || ic is Holdable)) { isWire = true; } if (HasTag("logic")) { isLogic = true; } - GameMain.LuaCs.HookBase.Call("item.created", this); + GameMain.LuaCs.Hook.Call("item.created", this); ApplyStatusEffects(ActionType.OnSpawn, 1.0f); Components.ForEach(c => c.ApplyStatusEffects(ActionType.OnSpawn, 1.0f)); @@ -2469,9 +2469,9 @@ namespace Barotrauma if (condition == 0.0f) { return; } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("item.use", new object[] { this, character, targetLimb })); + var should = GameMain.LuaCs.Hook.Call("item.use", new object[] { this, character, targetLimb }); - if (should.Bool()) + if (should != null && should.Value) return; bool remove = false; @@ -2507,9 +2507,9 @@ namespace Barotrauma { if (condition == 0.0f) { return; } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("item.secondaryUse", new object[] { this, character})); + var should = GameMain.LuaCs.Hook.Call("item.secondaryUse", this, character); - if (should.Bool()) + if (should != null && should.Value) return; bool remove = false; @@ -2851,8 +2851,8 @@ namespace Barotrauma } } - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("item.readPropertyChange", this, property, parentObject, allowEditing)); - if (result.Bool()) + var result = GameMain.LuaCs.Hook.Call("item.readPropertyChange", this, property, parentObject, allowEditing); + if (result != null && result.Value) return; Type type = property.PropertyType; @@ -3343,7 +3343,7 @@ namespace Barotrauma body = null; } - GameMain.LuaCs.HookBase.Call("item.removed", this); + GameMain.LuaCs.Hook.Call("item.removed", this); } public override void Remove() @@ -3427,7 +3427,7 @@ namespace Barotrauma RemoveProjSpecific(); - GameMain.LuaCs.HookBase.Call("item.removed", this); + GameMain.LuaCs.Hook.Call("item.removed", this); } partial void RemoveProjSpecific(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaGame.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaGame.cs index c13a332ed..82af1e3d9 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaGame.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaGame.cs @@ -324,14 +324,14 @@ namespace Barotrauma } } - public void AddCommand(string name, string help, object onExecute, object getValidArgs = null, bool isCheat = false) + public void AddCommand(string name, string help, CsAction onExecute, CsFunc getValidArgs = null, bool isCheat = false) { - var cmd = new DebugConsole.Command(name, help, (string[] arg1) => { GameMain.LuaCs.CallLuaFunction(onExecute, new object[] { arg1 }); }, + var cmd = new DebugConsole.Command(name, help, (string[] arg1) => { onExecute(arg1); }, () => { if (getValidArgs == null) return null; - var result = new LuaResult(GameMain.LuaCs.CallLuaFunction(getValidArgs, new object[] { })); - var obj = result.Object(); + var obj = getValidArgs(); + if (obj is LuaResult res) obj = res.Object(); if (obj is string[][]) return (string[][])obj; return null; }, isCheat); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaHook.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaHook.cs deleted file mode 100644 index 118f0718e..000000000 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaHook.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; - -namespace Barotrauma -{ - - partial class LuaCsSetup - { - // CSharp wrapper for LuaCsHook - public class LuaHook : LuaCsHookWrapper - { - public LuaHook(LuaCsHook hook) : base(hook) { } - - public class HookMethodTypeProxy - { - public HookMethodTypeProxy() { } - public const HookMethodType Before = Barotrauma.HookMethodType.Before; - public const HookMethodType After = Barotrauma.HookMethodType.After; - } - public static readonly HookMethodTypeProxy HookMethodType = new HookMethodTypeProxy(); - - public void HookMethod(string identifier, string className, string methodName, string[] parameterNames, object hookMethod, HookMethodType hookMethodType = Barotrauma.HookMethodType.Before) => - _hook.HookLuaMethod(identifier, className, methodName, parameterNames, hookMethod, hookMethodType); - - public void HookMethod(string identifier, string className, string methodName, object hookMethod, HookMethodType hookMethodType = Barotrauma.HookMethodType.Before) => - _hook.HookLuaMethod(identifier, className, methodName, null, hookMethod, hookMethodType); - - public void HookMethod(string className, string methodName, object hookMethod, HookMethodType hookMethodType = Barotrauma.HookMethodType.Before) => - _hook.HookLuaMethod("", className, methodName, null, hookMethod, hookMethodType); - - public void HookMethod(string className, string methodName, string[] parameterNames, object hookMethod, HookMethodType hookMethodType = Barotrauma.HookMethodType.Before) => - _hook.HookLuaMethod("", className, methodName, parameterNames, hookMethod, hookMethodType); - - public void Add(string name, string hookName, object function) => - _hook.AddLuaHook(name, hookName, function); - - public void EnqueueFunction(object function, params object[] args) => - _hook.EnqueueLuaFunction(function, args); - - public void EnqueueTimedFunction(float time, object function, params object[] args) => - _hook.EnqueueTimedLuaFunction(time, function, args); - } - } - -} \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaResult.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaResult.cs new file mode 100644 index 000000000..34bd9b0ff --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaResult.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MoonSharp.Interpreter; +using Microsoft.Xna.Framework; +using Barotrauma.Networking; +using Barotrauma.Items.Components; +using System.IO; +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 +{ + public class LuaResult + { + object result; + public LuaResult(object arg) + { + result = arg; + } + + public bool IsNull() + { + if (result == null) + return true; + + if (result is DynValue dynValue) + return dynValue.IsNil(); + + return false; + } + + public bool Bool() + { + if (result is DynValue dynValue) + { + return dynValue.CastToBool(); + } + + return false; + } + + public float Float() + { + if (result is DynValue dynValue) + { + var num = dynValue.CastToNumber(); + if (num == null) { return 0f; } + return (float)num.Value; + } + + return 0f; + } + + public double Double() + { + if (result is DynValue dynValue) + { + var num = dynValue.CastToNumber(); + if (num == null) { return 0f; } + return num.Value; + } + + return 0f; + } + + public string String() + { + if (result is DynValue dynValue) + { + var str = dynValue.CastToString(); + if (str == null) { return ""; } + return str; + } + + return ""; + } + + public object Object() + { + if (result is DynValue dynValue) + { + return dynValue.ToObject(); + } + + return null; + } + + public DynValue DynValue() + { + if (result is DynValue dynValue) + { + return dynValue; + } + + return null; + } + + public static implicit operator bool(LuaResult res) => res.Bool(); + public static implicit operator float(LuaResult res) => res.Float(); + public static implicit operator string(LuaResult res) => res.String(); + public static implicit operator double(LuaResult res) => res.Double(); + public static implicit operator DynValue(LuaResult res) => res.DynValue(); + } +} \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaCustomConverters.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaCustomConverters.cs index adddb77db..409701f9b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaCustomConverters.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaCustomConverters.cs @@ -23,6 +23,10 @@ namespace Barotrauma var function = v.Function; return (Func)((Fixture a, Vector2 b, Vector2 c, float d) => new LuaResult(function.Call(a, b, c, d)).Float()); }); + Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Closure), v => v.Function); + Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(CsAction), v => (CsAction)( args => GameMain.LuaCs.CallLuaFunction(v.Function, args) )); + Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(CsFunc), v => (CsFunc)( args => new LuaResult(GameMain.LuaCs.CallLuaFunction(v.Function, args)).Object() )); + Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(CsPatch), v => (CsPatch)( (self, args) => new LuaResult(GameMain.LuaCs.CallLuaFunction(v.Function, self, args)).Object() )); #if CLIENT RegisterAction(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaScriptLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaScriptLoader.cs index cff04ecdb..64ebceb3d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaScriptLoader.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaScriptLoader.cs @@ -13,14 +13,14 @@ namespace Barotrauma public override object LoadFile(string file, Table globalContext) { - if (!LuaFile.IsPathAllowedLuaException(file, false)) return null; + if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return null; return File.ReadAllText(file); } public override bool ScriptFileExists(string file) { - if (!LuaFile.IsPathAllowedLuaException(file, false)) return false; + if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return false; return File.Exists(file); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsHook.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsHook.cs index acdb5275e..c1462fbae 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsHook.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsHook.cs @@ -5,39 +5,21 @@ using MoonSharp.Interpreter; using HarmonyLib; using System.Collections.Generic; using System.Text; +using MoonSharp.Interpreter.Interop; namespace Barotrauma { - public enum HookMethodType - { - Before, After - } - - public delegate object CsHookDelegate(params object[] args); - public delegate object CsPatchDelegate(object self, params object[] args); - - public abstract class LuaCsHookWrapper { - - protected LuaCsHook _hook; - - public LuaCsHookWrapper(LuaCsHook hook) - { - _hook = hook; - } - - public void Remove(string name, string hookName) => - _hook.RemoveHook(name, hookName); - - public void Update() => - _hook.Update(); - - public object Call(string name, params object[] args) => - _hook.Call(name, args); - - } + public delegate void CsAction(params object[] args); + public delegate object CsFunc(params object[] args); + public delegate object CsPatch(object self, params object[] args); public class LuaCsHook { + public enum HookMethodType + { + Before, After + } + private class LuaHookFunction { public string name; @@ -51,82 +33,41 @@ namespace Barotrauma function = func; } } + private class LuaCsHookCallback + { + public string name; + public string hookName; + public CsFunc func; - private Dictionary> luaHookFunctions; - private Dictionary> csHookFunctions; + public LuaCsHookCallback(string name, string hookName, CsFunc func) + { + this.name = name; + this.hookName = hookName; + this.func = func; + } + } - private Dictionary> luaHookPrefixMethods; - private Dictionary> luaHookPostfixMethods; - private Dictionary> csHookPrefixMethods; - private Dictionary> csHookPostfixMethods; + private Dictionary> hookFunctions; - private Queue> queuedFunctionCalls; + private Dictionary> hookPrefixMethods; + private Dictionary> hookPostfixMethods; + + private Queue<(float, CsAction, object[])> queuedFunctionCalls; private LuaCsHook() { - luaHookFunctions = new Dictionary>(); - csHookFunctions = new Dictionary>(); + hookFunctions = new Dictionary>(); - luaHookPrefixMethods = new Dictionary>(); - luaHookPostfixMethods = new Dictionary>(); - csHookPrefixMethods = new Dictionary>(); - csHookPostfixMethods = new Dictionary>(); + hookPrefixMethods = new Dictionary>(); + hookPostfixMethods = new Dictionary>(); - queuedFunctionCalls = new Queue>(); + queuedFunctionCalls = new Queue<(float, CsAction, object[])>(); } private static LuaCsHook _inst; static LuaCsHook() => _inst = new LuaCsHook(); public static LuaCsHook Instance { get => _inst; } - - static void _hookLuaPatch(MethodBase __originalMethod, object[] __args, object __instance, out LuaResult result, HookMethodType hookMethodType) - { - result = new LuaResult(null); - -#if CLIENT - if (GameMain.GameSession?.IsRunning == false && GameMain.IsSingleplayer) - return; -#endif - - try - { - var funcAddr = ((long)__originalMethod.MethodHandle.GetFunctionPointer()); - HashSet<(string, object)> methodSet = null; - switch (hookMethodType) - { - case HookMethodType.Before: - _inst.luaHookPrefixMethods.TryGetValue(funcAddr, out methodSet); - break; - case HookMethodType.After: - _inst.luaHookPostfixMethods.TryGetValue(funcAddr, out methodSet); - break; - default: - break; - } - - if (methodSet != null) - { - var @params = __originalMethod.GetParameters(); - var ptable = new Dictionary(); - for (int i = 0; i < @params.Length; i++) - { - ptable.Add(@params[i].Name, __args[i]); - } - - foreach (var tuple in methodSet) - { - var luaResult = new LuaResult(GameMain.LuaCs.lua.Call(tuple.Item2, __instance, ptable)); - if (!luaResult.IsNull()) result = luaResult; - } - } - } - catch (Exception ex) - { - GameMain.LuaCs.HandleException(ex); - } - } - - static void _hookCsPatch(MethodBase __originalMethod, object[] __args, object __instance, ref object result, HookMethodType hookMethodType) + private static void _hookLuaCsPatch(MethodBase __originalMethod, object[] __args, object __instance, ref object result, HookMethodType hookMethodType) { #if CLIENT if (GameMain.GameSession?.IsRunning == false && GameMain.IsSingleplayer) @@ -135,14 +76,14 @@ namespace Barotrauma try { var funcAddr = ((long)__originalMethod.MethodHandle.GetFunctionPointer()); - HashSet<(string, CsPatchDelegate, ACsMod)> methodSet = null; + HashSet<(string, CsPatch, ACsMod)> methodSet = null; switch (hookMethodType) { case HookMethodType.Before: - _inst.csHookPrefixMethods.TryGetValue(funcAddr, out methodSet); + _inst.hookPrefixMethods.TryGetValue(funcAddr, out methodSet); break; case HookMethodType.After: - _inst.csHookPostfixMethods.TryGetValue(funcAddr, out methodSet); + _inst.hookPostfixMethods.TryGetValue(funcAddr, out methodSet); break; default: break; @@ -157,94 +98,78 @@ namespace Barotrauma args.Add(@params[i].Name, __args[i]); } - var outOfSocpe = new HashSet<(string, CsPatchDelegate, ACsMod)>(); + var outOfSocpe = new HashSet<(string, CsPatch, ACsMod)>(); foreach (var tuple in methodSet) { if (tuple.Item3 != null && tuple.Item3.IsDisposed) outOfSocpe.Add(tuple); else - result = tuple.Item2(__instance, args) ?? result; + { + var _result = tuple.Item2(__instance, args); + if (_result is LuaResult res && !res.IsNull()) result = _result; + else if (_result != null) result = _result; + } } foreach (var tuple in outOfSocpe) methodSet.Remove(tuple); } } catch (Exception ex) { - GameMain.LuaCs.HandleException(ex, exceptionType: LuaCsSetup.ExceptionType.CSharp); + GameMain.LuaCs.HandleException(ex, exceptionType: LuaCsSetup.ExceptionType.Both); } } - private static bool HookLuaPatchPrefix(MethodBase __originalMethod, object[] __args, object __instance) + private static bool HookLuaCsPatchPrefix(MethodBase __originalMethod, object[] __args, object __instance) { - _hookLuaPatch(__originalMethod, __args, __instance, out LuaResult result, HookMethodType.Before); - - return result.IsNull(); - } - - private static bool HookLuaPatchRetPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) - { - _hookLuaPatch(__originalMethod, __args, __instance, out LuaResult result, HookMethodType.Before); - - if (!result.IsNull()) + object result = null; + _hookLuaCsPatch(__originalMethod, __args, __instance, ref result, HookMethodType.Before); + if (result != null) { - - if (__originalMethod is MethodInfo mi) - { - __result = result.DynValue().ToObject(mi.ReturnType); - } - else - { - __result = result.Object(); - } - + if (result is LuaResult res) return res.IsNull(); return false; } - - return true; + else return true; } - - private static void HookLuaPatchPostfix(MethodBase __originalMethod, object[] __args, object __instance) + private static void HookLuaCsPatchPostfix(MethodBase __originalMethod, object[] __args, object __instance) { - _hookLuaPatch(__originalMethod, __args, __instance, out LuaResult result, HookMethodType.After); + object result = null; + _hookLuaCsPatch(__originalMethod, __args, __instance, ref result, HookMethodType.After); } - private static void HookLuaPatchRetPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) + private static bool HookLuaCsPatchRetPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) { - _hookLuaPatch(__originalMethod, __args, __instance, out LuaResult result, HookMethodType.After); - - if (!result.IsNull()) + _hookLuaCsPatch(__originalMethod, __args, __instance, ref __result, HookMethodType.Before); + if (__result != null) { - if (__originalMethod is MethodInfo mi) + if (__result is LuaResult res) { - __result = result.DynValue().ToObject(mi.ReturnType); + if (!res.IsNull() && __originalMethod is MethodInfo mi) __result = res.DynValue().ToObject(mi.ReturnType); + else __result = res.Object(); } - else + return false; + } + else return true; + } + private static void HookLuaCsPatchRetPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) + { + _hookLuaCsPatch(__originalMethod, __args, __instance, ref __result, HookMethodType.After); + if (__result != null) + { + if (__result is LuaResult res) { - __result = result.Object(); + if (!res.IsNull() && __originalMethod is MethodInfo mi) __result = res.DynValue().ToObject(mi.ReturnType); + else __result = res.Object(); } } } - private static bool HookCsPatchPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) - { - _hookCsPatch(__originalMethod, __args, __instance, ref __result, HookMethodType.Before); - - if (__result != null) return false; - else return true; - } - private static void HookCsPatchPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) => - _hookCsPatch(__originalMethod, __args, __instance, ref __result, HookMethodType.After); - private const BindingFlags DefaultBindingFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - private static MethodInfo _miHookLuaPatchPrefix = typeof(LuaCsHook).GetMethod("HookLuaPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static); - private static MethodInfo _miHookLuaPatchRetPrefix = typeof(LuaCsHook).GetMethod("HookLuaPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static); - private static MethodInfo _miHookLuaPatchPostfix = typeof(LuaCsHook).GetMethod("HookLuaPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static); - private static MethodInfo _miHookLuaPatchRetPostfix = typeof(LuaCsHook).GetMethod("HookLuaPatchRetPostfix", BindingFlags.NonPublic | BindingFlags.Static); - - private static MethodInfo _miHookCsPatchRetPrefix = typeof(LuaCsHook).GetMethod("HookCsPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static); - private static MethodInfo _miHookCsPatchRetPostfix = typeof(LuaCsHook).GetMethod("HookCsPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaCsPatchPrefix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaCsPatchPostfix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaCsPatchRetPrefix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaCsPatchRetPostfix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchRetPostfix", BindingFlags.NonPublic | BindingFlags.Static); private static MethodInfo ResolveMethod(string where, string className, string methodName, string[] parameterNames) { @@ -277,216 +202,145 @@ namespace Barotrauma return methodInfo; } - public void HookLuaMethod(string identifier, string className, string methodName, string[] parameterNames, object hookMethod, HookMethodType hookMethodType = HookMethodType.Before) + public void HookMethod(string identifier, MethodInfo method, CsPatch patch, HookMethodType hookType = HookMethodType.Before, ACsMod owner = null) { - - MethodInfo methodInfo = ResolveMethod("HookMethod", className, methodName, parameterNames); - if (methodInfo == null) return; - - identifier = identifier.ToLower(); - var funcAddr = ((long)methodInfo.MethodHandle.GetFunctionPointer()); - var patches = Harmony.GetPatchInfo(methodInfo); - - if (hookMethodType == HookMethodType.Before) - { - if (methodInfo.ReturnType == typeof(void)) - { - if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaPatchPrefix) == null) - { - GameMain.LuaCs.harmony.Patch(methodInfo, prefix: new HarmonyMethod(_miHookLuaPatchPrefix)); - } - } - else - { - if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaPatchRetPrefix) == null) - { - GameMain.LuaCs.harmony.Patch(methodInfo, prefix: new HarmonyMethod(_miHookLuaPatchRetPrefix)); - } - } - - if (luaHookPrefixMethods.TryGetValue(funcAddr, out HashSet<(string, object)> methodSet)) - { - if (identifier != "") - { - methodSet.RemoveWhere(tuple => tuple.Item1 == identifier); - } - if (hookMethod != null) - { - methodSet.Add((identifier, hookMethod)); - } - } - else if (hookMethod != null) - { - luaHookPrefixMethods.Add(funcAddr, new HashSet<(string, object)>() { (identifier, hookMethod) }); - } - - } - else if (hookMethodType == HookMethodType.After) - { - if (methodInfo.ReturnType == typeof(void)) - { - if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaPatchPostfix) == null) - { - GameMain.LuaCs.harmony.Patch(methodInfo, postfix: new HarmonyMethod(_miHookLuaPatchPostfix)); - } - } - else - { - if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaPatchRetPostfix) == null) - { - GameMain.LuaCs.harmony.Patch(methodInfo, postfix: new HarmonyMethod(_miHookLuaPatchRetPostfix)); - } - } - - if (luaHookPostfixMethods.TryGetValue(funcAddr, out HashSet<(string, object)> methodSet)) - { - if (identifier != "") - { - methodSet.RemoveWhere(tuple => tuple.Item1 == identifier); - } - if (hookMethod != null) - { - methodSet.Add((identifier, hookMethod)); - } - } - else if (hookMethod != null) - { - luaHookPostfixMethods.Add(funcAddr, new HashSet<(string, object)>() { (identifier, hookMethod) }); - } - - } - - } - - public void HookCsMethod(string identifier, MethodInfo method, CsPatchDelegate hook, HookMethodType hookType = HookMethodType.Before, ACsMod owner = null) - { - if (identifier == null || method == null || hook == null) throw new ArgumentNullException("Identifier, Method and Hook arguments must not be null."); + if (identifier == null || method == null || patch == null) throw new ArgumentNullException("Identifier, Method and Patch arguments must not be null."); var funcAddr = ((long)method.MethodHandle.GetFunctionPointer()); var patches = Harmony.GetPatchInfo(method); if (hookType == HookMethodType.Before) { - if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookCsPatchRetPrefix) == null) - { - GameMain.LuaCs.harmony.Patch(method, prefix: new HarmonyMethod(_miHookCsPatchRetPrefix)); + if (method.ReturnType != typeof(void)) + { + if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPrefix) == null) + { + GameMain.LuaCs.harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchRetPrefix)); + } + } + else + { + if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchPrefix) == null) + { + GameMain.LuaCs.harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchPrefix)); + } } - if (csHookPrefixMethods.TryGetValue(funcAddr, out HashSet<(string, CsPatchDelegate, ACsMod)> methodSet)) + if (hookPrefixMethods.TryGetValue(funcAddr, out HashSet<(string, CsPatch, ACsMod)> methodSet)) { methodSet.RemoveWhere(tuple => tuple.Item1 == identifier); - methodSet.Add((identifier, hook, owner)); + methodSet.Add((identifier, patch, owner)); } - else if (hook != null) + else if (patch != null) { - csHookPrefixMethods.Add(funcAddr, new HashSet<(string, CsPatchDelegate, ACsMod)>() { (identifier, hook, owner) }); + hookPrefixMethods.Add(funcAddr, new HashSet<(string, CsPatch, ACsMod)>() { (identifier, patch, owner) }); } } else if (hookType == HookMethodType.After) { - if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookCsPatchRetPrefix) == null) + if (method.ReturnType != typeof(void)) { - GameMain.LuaCs.harmony.Patch(method, postfix: new HarmonyMethod(_miHookCsPatchRetPostfix)); + if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPostfix) == null) + { + GameMain.LuaCs.harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchRetPostfix)); + } + } + else + { + if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchPostfix) == null) + { + GameMain.LuaCs.harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchPostfix)); + } } - if (csHookPostfixMethods.TryGetValue(funcAddr, out HashSet<(string, CsPatchDelegate, ACsMod)> methodSet)) + if (hookPostfixMethods.TryGetValue(funcAddr, out HashSet<(string, CsPatch, ACsMod)> methodSet)) { methodSet.RemoveWhere(tuple => tuple.Item1 == identifier); - methodSet.Add((identifier, hook, owner)); + methodSet.Add((identifier, patch, owner)); } - else if (hook != null) + else if (patch != null) { - csHookPostfixMethods.Add(funcAddr, new HashSet<(string, CsPatchDelegate, ACsMod)>() { (identifier, hook, owner) }); + hookPostfixMethods.Add(funcAddr, new HashSet<(string, CsPatch, ACsMod)>() { (identifier, patch, owner) }); } } } - public void RemoveLuaPatch(string identifier, string className, string methodName, string[] parameterNames, HookMethodType hookType = HookMethodType.Before) - { - MethodInfo methodInfo = ResolveMethod("UnhookMathod", className, methodName, parameterNames); + protected void HookMethod(string identifier, string className, string methodName, string[] parameterNames, CsPatch patch, HookMethodType hookMethodType = HookMethodType.Before) + { + + MethodInfo methodInfo = ResolveMethod("HookMethod", className, methodName, parameterNames); if (methodInfo == null) return; - RemovePatch(identifier, methodInfo, hookType); + HookMethod(identifier, methodInfo, patch, hookMethodType); } - public void RemovePatch(string identifier, MethodInfo method, HookMethodType hookType = HookMethodType.Before) + protected void HookMethod(string identifier, string className, string methodName, CsPatch patch, HookMethodType hookMethodType = HookMethodType.Before) => + HookMethod(identifier, className, methodName, null, patch, hookMethodType); + protected void HookMethod(string className, string methodName, CsPatch patch, HookMethodType hookMethodType = HookMethodType.Before) => + HookMethod("", className, methodName, null, patch, hookMethodType); + protected void HookMethod(string className, string methodName, string[] parameterNames, CsPatch patch, HookMethodType hookMethodType = HookMethodType.Before) => + HookMethod("", className, methodName, parameterNames, patch, hookMethodType); + + + public void UnhookMethod(string identifier, MethodInfo method, HookMethodType hookType = HookMethodType.Before) { var funcAddr = ((long)method.MethodHandle.GetFunctionPointer()); - Dictionary> luaMethods; - Dictionary> csMethods; - if (hookType == HookMethodType.Before) - { - luaMethods = luaHookPrefixMethods; - csMethods = csHookPrefixMethods; - } - else if (hookType == HookMethodType.After) - { - luaMethods = luaHookPostfixMethods; - csMethods = csHookPostfixMethods; - } + Dictionary> methods; + if (hookType == HookMethodType.Before) methods = hookPrefixMethods; + else if (hookType == HookMethodType.After) methods = hookPostfixMethods; else throw null; - if (luaMethods.ContainsKey(funcAddr)) luaMethods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier); - if (csMethods.ContainsKey(funcAddr)) csMethods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier); + if (methods.ContainsKey(funcAddr)) methods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier); } - - - public void EnqueueLuaFunction(object function, params object[] args) + protected void UnhookMethod(string identifier, string className, string methodName, string[] parameterNames, HookMethodType hookType = HookMethodType.Before) { - queuedFunctionCalls.Enqueue(new Tuple(0, function, args)); + MethodInfo methodInfo = ResolveMethod("UnhookMathod", className, methodName, parameterNames); + if (methodInfo == null) return; + UnhookMethod(identifier, methodInfo, hookType); } - public void EnqueueTimedLuaFunction(float time, object function, params object[] args) + + public void Enqueue(CsAction action, params object[] args) { - queuedFunctionCalls.Enqueue(new Tuple(time, function, args)); + queuedFunctionCalls.Enqueue((0, action, args)); } - - - public void AddLuaHook(string name, string hookName, object function) + public void EnqueueTimed(float time, CsAction action, params object[] args) { - if (name == null || hookName == null || function == null) return; - - name = name.ToLower(); - - if (!luaHookFunctions.ContainsKey(name)) - luaHookFunctions.Add(name, new Dictionary()); - - luaHookFunctions[name][hookName] = new LuaHookFunction(name, hookName, function); + queuedFunctionCalls.Enqueue((time, action, args)); } - public void AddCsHook(string name, string hookName, CsHookDelegate hook, ACsMod owner = null) + protected void EnqueueFunction(CsAction function, params object[] args) => Enqueue(function, args); + protected void EnqueueTimedFunction(float time, CsAction function, params object[] args) => EnqueueTimed(time, function, args); + + + public void Add(string name, string hookName, CsFunc hook, ACsMod owner = null) { if (name == null || hookName == null || hook == null) throw new ArgumentNullException("Names and Hook must not be null"); - if (!csHookFunctions.ContainsKey(name)) - csHookFunctions.Add(name, new Dictionary()); + if (!hookFunctions.ContainsKey(name)) + hookFunctions.Add(name, new Dictionary()); - csHookFunctions[name][hookName] = (hook, owner); + hookFunctions[name][hookName] = (new LuaCsHookCallback(name, hookName, hook), owner); } - public void RemoveHook(string name, string hookName) + public void Remove(string name, string hookName) { if (name == null || hookName == null) return; name = name.ToLower(); - if (luaHookFunctions.ContainsKey(name) && luaHookFunctions[name].ContainsKey(hookName)) - luaHookFunctions[name].Remove(hookName); - if (csHookFunctions.ContainsKey(name) && csHookFunctions[name].ContainsKey(hookName)) - csHookFunctions[name].Remove(hookName); + if (hookFunctions.ContainsKey(name) && hookFunctions[name].ContainsKey(hookName)) + hookFunctions[name].Remove(hookName); } public void Clear() { - luaHookFunctions.Clear(); - csHookFunctions.Clear(); + hookFunctions.Clear(); - luaHookPrefixMethods.Clear(); - luaHookPostfixMethods.Clear(); - csHookPrefixMethods.Clear(); - csHookPostfixMethods.Clear(); + hookPrefixMethods.Clear(); + hookPostfixMethods.Clear(); queuedFunctionCalls.Clear(); @@ -498,43 +352,53 @@ namespace Barotrauma { try { - if (queuedFunctionCalls.TryPeek(out Tuple result)) + if (queuedFunctionCalls.TryPeek(out (float, CsAction, object[]) result)) { if (Timing.TotalTime >= result.Item1) { - GameMain.LuaCs.CallLuaFunction(result.Item2, result.Item3); - + result.Item2(result.Item3); queuedFunctionCalls.Dequeue(); } } } catch (Exception ex) { - GameMain.LuaCs.HandleException(ex, $"queuedFunctionCalls was {queuedFunctionCalls}"); + GameMain.LuaCs.HandleException(ex, $"queuedFunctionCalls was {queuedFunctionCalls}", LuaCsSetup.ExceptionType.Both); } } - public object Call(string name, params object[] args) + public T Call(string name, params object[] args) { + if ( + typeof(T) != typeof(object) && + !name.StartsWith("think") && + !name.StartsWith("gapOxygenUpdate") && + !name.StartsWith("statusEffect") + ) Console.WriteLine($" --== '{name}'"); #if CLIENT if (GameMain.GameSession?.IsRunning == false && GameMain.IsSingleplayer) - return null; + //return null; + return default(T); #endif - if (GameMain.LuaCs == null) return null; - if (name == null) return null; + //if (GameMain.LuaCs == null) return null; + //if (name == null) return null; + if (GameMain.LuaCs == null) return default(T); + if (name == null) return default(T); if (args == null) { args = new object[] { }; } name = name.ToLower(); - if (!luaHookFunctions.ContainsKey(name)) - return null; + if (!hookFunctions.ContainsKey(name)) + //return null; + return default(T); - object lastResult = null; + //object lastResult = null; + T lastResult = default(T); - if (csHookFunctions.ContainsKey(name)) + if (hookFunctions.ContainsKey(name)) { var outOfScope = new List(); - foreach ((var key, var tuple) in csHookFunctions[name]) + foreach ((var key, var tuple) in hookFunctions[name]) { if (tuple.Item2 != null && tuple.Item2.IsDisposed) outOfScope.Add(key); @@ -542,8 +406,9 @@ namespace Barotrauma { try { - var result = tuple.Item1(args); - if (result != null) lastResult = result; + var result = tuple.Item1.func(args); + if (result is LuaResult lRes && !lRes.IsNull()) lastResult = lRes.DynValue().ToObject(); + else if (result != null && result is T cRes) lastResult = cRes; } catch (Exception e) { @@ -551,40 +416,15 @@ namespace Barotrauma foreach (var arg in args) argsSb.Append(arg + " "); GameMain.LuaCs.HandleException( e, $"Error in Hook '{name}'->'{key}', with args '{argsSb}':\n{e}", - LuaCsSetup.ExceptionType.CSharp); + LuaCsSetup.ExceptionType.Both); } } } - foreach (var key in outOfScope) csHookFunctions[name].Remove(key); - } - - if (luaHookFunctions.ContainsKey(name)) - { - foreach (LuaHookFunction hf in luaHookFunctions[name].Values) - { - try - { - if (hf.function is Closure) - { - var result = GameMain.LuaCs.lua.Call(hf.function, args); - if (!result.IsNil()) - lastResult = result; - } - } - catch (Exception e) - { - StringBuilder argsSb = new StringBuilder(); - foreach (var arg in args) - { - argsSb.Append(arg + " "); - } - - GameMain.LuaCs.HandleException(e, $"Error in Hook '{name}'->'{hf.hookName}', with args '{argsSb}'"); - } - } + foreach (var key in outOfScope) hookFunctions[name].Remove(key); } return lastResult; } + public object Call(string name, params object[] args) => Call(name, args); } } \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs index 05913e2a0..f81505cea 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs @@ -9,6 +9,8 @@ using MoonSharp.Interpreter.Interop; using System.IO.Compression; using HarmonyLib; using System.Runtime.CompilerServices; +using System.Linq; +using System.Reflection; [assembly: InternalsVisibleTo("NetScriptAssembly", AllInternalsVisible = true)] namespace Barotrauma @@ -20,12 +22,10 @@ namespace Barotrauma public Script lua; - private LuaHook luaHook; - public CsHook Hook { get; private set; } - internal LuaCsHook HookBase { get; private set; } + internal LuaCsHook Hook { get; private set; } public LuaGame game; - public LuaNetworking networking; + public LuaCsNetworking networking; public Harmony harmony; public LuaScriptLoader luaScriptLoader; @@ -33,12 +33,10 @@ namespace Barotrauma public LuaCsSetup() { - HookBase = LuaCsHook.Instance; - Hook = new CsHook(HookBase); - luaHook = new LuaHook(HookBase); + Hook = LuaCsHook.Instance; game = new LuaGame(); - networking = new LuaNetworking(); + networking = new LuaCsNetworking(); } @@ -66,13 +64,15 @@ namespace Barotrauma public enum ExceptionType { Lua, - CSharp + CSharp, + Both } public void HandleException(Exception ex, string extra = "", ExceptionType exceptionType = ExceptionType.Lua) { if (!string.IsNullOrWhiteSpace(extra)) if (exceptionType == ExceptionType.Lua) PrintError(extra); - else PrintCsError(extra); + else if (exceptionType == ExceptionType.CSharp) PrintCsError(extra); + else PrintBothError(extra); if (ex is InterpreterException) { @@ -84,7 +84,8 @@ namespace Barotrauma else { if (exceptionType == ExceptionType.Lua) PrintError(ex); - else PrintCsError(ex); + else if (exceptionType == ExceptionType.CSharp) PrintCsError(ex); + else PrintBothError(ex); } } @@ -119,9 +120,11 @@ namespace Barotrauma #if SERVER private void PrintError(object message) => PrintErrorBase("[SV LUA ERROR] ", message, "nil"); public static void PrintCsError(object message) => PrintErrorBase("[SV CS ERROR] ", message, "Null"); + public static void PrintBothError(object message) => PrintErrorBase("[SV ERROR] ", message, "Null"); #else private void PrintError(object message) => PrintErrorBase("[CL LUA ERROR] ", message, "nil"); public static void PrintCsError(object message) => PrintErrorBase("[CL CS ERROR] ", message, "Null"); + public static void PrintBothError(object message) => PrintErrorBase("[CL ERROR] ", message, "Null"); #endif private static void PrintMessageBase(string prefix, object message, string empty) @@ -172,8 +175,8 @@ namespace Barotrauma public DynValue DoFile(string file, Table globalContext = null, string codeStringFriendly = null) { - if (!LuaFile.IsPathAllowedLuaException(file, false)) return null; - if (!LuaFile.Exists(file)) + if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return null; + if (!LuaCsFile.Exists(file)) { HandleException(new Exception($"dofile: File {file} not found.")); return null; @@ -210,8 +213,8 @@ namespace Barotrauma public DynValue LoadFile(string file, Table globalContext = null, string codeStringFriendly = null) { - if (!LuaFile.IsPathAllowedLuaException(file, false)) return null; - if (!LuaFile.Exists(file)) + if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return null; + if (!LuaCsFile.Exists(file)) { HandleException(new Exception($"loadfile: File {file} not found.")); return null; @@ -266,22 +269,22 @@ namespace Barotrauma public void Update() { - HookBase?.Update(); + Hook?.Update(); } public void Stop() { foreach (var mod in ACsMod.LoadedMods.ToArray()) mod.Dispose(); ACsMod.LoadedMods.Clear(); - HookBase?.Call("stop"); + Hook?.Call("stop"); game?.Stop(); //harmony?.UnpatchAll(); - //HookBase = new LuaCsHook(); - HookBase.Clear(); + //Hook = new LuaCsHook(); + Hook.Clear(); game = new LuaGame(); - networking = new LuaNetworking(); + networking = new LuaCsNetworking(); luaScriptLoader = null; } @@ -321,21 +324,34 @@ namespace Barotrauma harmony = new Harmony("com.LuaForBarotrauma"); harmony.UnpatchAll(); - //HookBase = new LuaCsHook(); + //Hook = new LuaCsHook(); game = new LuaGame(); - networking = new LuaNetworking(); + networking = new LuaCsNetworking(); //UserData.RegisterType(); - UserData.RegisterType(); UserData.RegisterType(); - UserData.RegisterType(); - UserData.RegisterType(); - UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); UserData.RegisterType(); UserData.RegisterType(); lua.Globals["printerror"] = (Action)PrintError; + var hookType = UserData.RegisterType(); + var hookDesc = (StandardUserDataDescriptor)hookType; + typeof(LuaCsHook).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).ToList().ForEach(m => { + if ( + m.Name.Contains("HookMethod") || + m.Name.Contains("UnhookMethod") || + m.Name.Contains("EnqueueFunction") || + m.Name.Contains("EnqueueTimedFunction") + ) + { + hookDesc.AddMember(m.Name, new MethodMemberDescriptor(m, InteropAccessMode.Default)); + } + }); + lua.Globals["setmodulepaths"] = (Action)SetModulePaths; lua.Globals["dofile"] = (Func)DoFile; @@ -347,13 +363,12 @@ namespace Barotrauma lua.Globals["LuaUserData"] = UserData.CreateStatic(); lua.Globals["Game"] = game; - //lua.Globals["Hook"] = HookBase; - lua.Globals["Hook"] = luaHook; - lua.Globals["Timer"] = new LuaTimer(); - lua.Globals["File"] = UserData.CreateStatic(); + lua.Globals["Hook"] = Hook; + lua.Globals["Timer"] = new LuaCsTimer(); + lua.Globals["File"] = UserData.CreateStatic(); lua.Globals["Networking"] = networking; - bool isServer = true; + bool isServer; #if SERVER isServer = true; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaClasses.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs similarity index 69% rename from Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaClasses.cs rename to Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs index f68699b0a..15560fb78 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses/LuaClasses.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using MoonSharp.Interpreter; @@ -17,7 +17,7 @@ using System.Diagnostics; namespace Barotrauma { - public partial class LuaTimer + public partial class LuaCsTimer { public static long LastUpdateTime = 0; @@ -29,9 +29,9 @@ namespace Barotrauma } } - public void Wait(object function, int millisecondDelay) + public void Wait(CsAction action, int millisecondDelay) { - GameMain.LuaCs.HookBase.EnqueueTimedLuaFunction((float)Timing.TotalTime + (millisecondDelay / 1000f), function); + GameMain.LuaCs.Hook.EnqueueTimed((float)Timing.TotalTime + (millisecondDelay / 1000f), action); } public static double GetTime() @@ -49,7 +49,7 @@ namespace Barotrauma } } - partial class LuaFile + partial class LuaCsFile { public static bool CanReadFromPath(string path) { @@ -115,7 +115,7 @@ namespace Barotrauma return false; } - public static bool IsPathAllowedLuaException(string path, bool write = true) + public static bool IsPathAllowedException(string path, bool write = true, LuaCsSetup.ExceptionType exceptionType = LuaCsSetup.ExceptionType.Both) { if (write) { @@ -123,9 +123,9 @@ namespace Barotrauma return true; else GameMain.LuaCs.HandleException(new Exception("File access to \"" + path + "\" not allowed.")); - } - else - { + } + else + { if (CanReadFromPath(path)) return true; else @@ -134,10 +134,14 @@ namespace Barotrauma return false; } + public static bool IsPathAllowedLuaException(string path, bool write = true) => + IsPathAllowedException(path, write, LuaCsSetup.ExceptionType.Lua); + public static bool IsPathAllowedCsException(string path, bool write = true) => + IsPathAllowedException(path, write, LuaCsSetup.ExceptionType.CSharp); public static string Read(string path) { - if (!IsPathAllowedLuaException(path, false)) + if (!IsPathAllowedException(path, false)) return ""; return File.ReadAllText(path); @@ -145,7 +149,7 @@ namespace Barotrauma public static void Write(string path, string text) { - if (!IsPathAllowedLuaException(path)) + if (!IsPathAllowedException(path)) return; File.WriteAllText(path, text); @@ -153,7 +157,7 @@ namespace Barotrauma public static bool Exists(string path) { - if (!IsPathAllowedLuaException(path, false)) + if (!IsPathAllowedException(path, false)) return false; return File.Exists(path); @@ -161,7 +165,7 @@ namespace Barotrauma public static bool CreateDirectory(string path) { - if (!IsPathAllowedLuaException(path)) + if (!IsPathAllowedException(path)) return false; Directory.CreateDirectory(path); @@ -171,7 +175,7 @@ namespace Barotrauma public static bool DirectoryExists(string path) { - if (!IsPathAllowedLuaException(path, false)) + if (!IsPathAllowedException(path, false)) return false; return Directory.Exists(path); @@ -179,7 +183,7 @@ namespace Barotrauma public static string[] GetFiles(string path) { - if (!IsPathAllowedLuaException(path, false)) + if (!IsPathAllowedException(path, false)) return null; return Directory.GetFiles(path); @@ -187,7 +191,7 @@ namespace Barotrauma public static string[] GetDirectories(string path) { - if (!IsPathAllowedLuaException(path, false)) + if (!IsPathAllowedException(path, false)) return new string[] { }; return Directory.GetDirectories(path); @@ -195,7 +199,7 @@ namespace Barotrauma public static string[] DirSearch(string sDir) { - if (!IsPathAllowedLuaException(sDir, false)) + if (!IsPathAllowedException(sDir, false)) return new string[] { }; List files = new List(); @@ -225,11 +229,10 @@ namespace Barotrauma } } - partial class LuaNetworking + partial class LuaCsNetworking { public bool restrictMessageSize = true; - - public Dictionary LuaNetReceives = new Dictionary(); + public Dictionary LuaCsNetReceives = new Dictionary(); #if SERVER [MoonSharpHidden] @@ -238,12 +241,11 @@ namespace Barotrauma if (header == ClientPacketHeader.LUA_NET_MESSAGE) { string netMessageName = netMessage.ReadString(); - if (LuaNetReceives[netMessageName] is Closure) - GameMain.LuaCs.CallLuaFunction(LuaNetReceives[netMessageName], new object[] { netMessage, client }); + if (LuaCsNetReceives.ContainsKey(netMessageName)) LuaCsNetReceives[netMessageName](netMessage, client); } else { - GameMain.LuaCs.HookBase.Call("netMessageReceived", netMessage, header, client); + GameMain.LuaCs.Hook.Call("netMessageReceived", netMessage, header, client); } } @@ -254,19 +256,17 @@ namespace Barotrauma if (header == ServerPacketHeader.LUA_NET_MESSAGE) { string netMessageName = netMessage.ReadString(); - if (LuaNetReceives[netMessageName] is Closure) - GameMain.LuaCs.lua.Call(LuaNetReceives[netMessageName], new object[] { netMessage, client }); + if (LuaCsNetReceives.ContainsKey(netMessageName)) LuaCsNetReceives[netMessageName](netMessage, client); } else { - GameMain.LuaCs.HookBase.Call("netMessageReceived", netMessage, header, client); + GameMain.LuaCs.Hook.Call("netMessageReceived", netMessage, header, client); } } #endif - - public void Receive(string netMessageName, object callback) + public void Receive(string netMessageName, CsAction callback) { - LuaNetReceives[netMessageName] = callback; + LuaCsNetReceives[netMessageName] = callback; } public IWriteMessage Start(string netMessageName) @@ -275,7 +275,7 @@ namespace Barotrauma #if SERVER message.Write((byte)ServerPacketHeader.LUA_NET_MESSAGE); #else - message.Write((byte)ClientPacketHeader.LUA_NET_MESSAGE); + message.Write((byte)ClientPacketHeader.LUA_NET_MESSAGE); #endif message.Write(netMessageName); return ((IWriteMessage)message); @@ -304,13 +304,13 @@ namespace Barotrauma } } #else - public void Send(IWriteMessage netMessage, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable) - { - GameMain.Client.ClientPeer.Send(netMessage, deliveryMethod); - } + public void Send(IWriteMessage netMessage, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable) + { + GameMain.Client.ClientPeer.Send(netMessage, deliveryMethod); + } #endif - public void RequestPostHTTP(string url, object callback, string data, string contentType = "application/json") + public void RequestPostHTTP(string url, CsAction callback, string data, string contentType = "application/json") { try { @@ -327,22 +327,22 @@ namespace Barotrauma { var httpResponse = httpWebRequest.EndGetResponse(result); using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - GameMain.LuaCs.HookBase.EnqueueLuaFunction(callback, streamReader.ReadToEnd()); + GameMain.LuaCs.Hook.Enqueue(callback, streamReader.ReadToEnd()); } catch (Exception e) { - GameMain.LuaCs.HookBase.EnqueueLuaFunction(callback, e.ToString()); + GameMain.LuaCs.Hook.Enqueue(callback, e.ToString()); } }), null); } catch (Exception e) { - GameMain.LuaCs.HookBase.EnqueueLuaFunction(callback, e.ToString()); + GameMain.LuaCs.Hook.Enqueue(callback, e.ToString()); } } - public void RequestGetHTTP(string url, object callback) + public void RequestGetHTTP(string url, CsAction callback) { try { @@ -354,17 +354,17 @@ namespace Barotrauma { var httpResponse = httpWebRequest.EndGetResponse(result); using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - GameMain.LuaCs.HookBase.EnqueueLuaFunction(callback, streamReader.ReadToEnd()); + GameMain.LuaCs.Hook.Enqueue(callback, streamReader.ReadToEnd()); } catch (Exception e) { - GameMain.LuaCs.HookBase.EnqueueLuaFunction(callback, e.ToString()); + GameMain.LuaCs.Hook.Enqueue(callback, e.ToString()); } }), null); } catch (Exception e) { - GameMain.LuaCs.HookBase.EnqueueLuaFunction(callback, e.ToString()); + GameMain.LuaCs.Hook.Enqueue(callback, e.ToString()); } } @@ -393,90 +393,4 @@ namespace Barotrauma } } -} - -public class LuaResult -{ - object result; - public LuaResult(object arg) - { - result = arg; - } - - public bool IsNull() - { - if (result == null) - return true; - - if (result is DynValue dynValue) - return dynValue.IsNil(); - - return false; - } - - public bool Bool() - { - if (result is DynValue dynValue) - { - return dynValue.CastToBool(); - } - - return false; - } - - public float Float() - { - if (result is DynValue dynValue) - { - var num = dynValue.CastToNumber(); - if (num == null) { return 0f; } - return (float)num.Value; - } - - return 0f; - } - - public double Double() - { - if (result is DynValue dynValue) - { - var num = dynValue.CastToNumber(); - if (num == null) { return 0f; } - return num.Value; - } - - return 0f; - } - - public string String() - { - if (result is DynValue dynValue) - { - var str = dynValue.CastToString(); - if (str == null) { return ""; } - return str; - } - - return ""; - } - - public object Object() - { - if (result is DynValue dynValue) - { - return dynValue.ToObject(); - } - - return null; - } - - public DynValue DynValue() - { - if (result is DynValue dynValue) - { - return dynValue; - } - - return null; - } } \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs index 447d75b29..ec4803185 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs @@ -660,10 +660,9 @@ namespace Barotrauma if (Math.Max(hull1.WorldSurface + hull1.WaveY[hull1.WaveY.Length - 1], hull2.WorldSurface + hull2.WaveY[0]) > WorldRect.Y) { return; } } - var should = new LuaResult(GameMain.LuaCs.HookBase.Call("gapOxygenUpdate", this, hull1, hull2)); + var should = GameMain.LuaCs.Hook.Call("gapOxygenUpdate", this, hull1, hull2); - if (should.Bool()) - return; + if (should != null && should.Value) return; float totalOxygen = hull1.Oxygen + hull2.Oxygen; float totalVolume = hull1.Volume + hull2.Volume; diff --git a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs index 47f0da02c..0fdf89fa9 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs @@ -1201,26 +1201,26 @@ namespace Barotrauma { if (entity is Item item) { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("statusEffect.apply." + item.Prefab.Identifier, this, deltaTime, entity, targets, worldPosition)); + var result = GameMain.LuaCs.Hook.Call("statusEffect.apply." + item.Prefab.Identifier, this, deltaTime, entity, targets, worldPosition); - if (result.Bool()) + if (result != null && result.Value) return; } if (entity is Character character) { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call("statusEffect.apply." + character.SpeciesName, this, deltaTime, entity, targets, worldPosition)); + var result = GameMain.LuaCs.Hook.Call("statusEffect.apply." + character.SpeciesName, this, deltaTime, entity, targets, worldPosition); - if (result.Bool()) + if (result != null && result.Value) return; } } foreach (string luaHooks in luaHook) { - var result = new LuaResult(GameMain.LuaCs.HookBase.Call(luaHooks, this, deltaTime, entity, targets, worldPosition)); + var result = GameMain.LuaCs.Hook.Call(luaHooks, this, deltaTime, entity, targets, worldPosition); - if (result.Bool()) + if (result != null && result.Value) return; }