From 8ab7b96d878fa871a0b7c08c75c70955644cbcff Mon Sep 17 00:00:00 2001 From: Evil Factory <36804725+evilfactory@users.noreply.github.com> Date: Tue, 12 Jan 2021 20:52:35 -0300 Subject: [PATCH] my attempt --- .../BarotraumaClient/WindowsClient.csproj | 1 + .../ServerSource/DebugConsole.cs | 20 +- .../BarotraumaServer/ServerSource/GameMain.cs | 6 + .../ServerSource/Lua/LuaCustomConverters.cs | 59 +++++ .../ServerSource/Lua/LuaScriptLoader.cs | 62 +++++ .../ServerSource/Lua/LuaSetup.cs | 222 ++++++++++++++++++ .../ServerSource/Networking/ChatMessage.cs | 6 + .../ServerSource/Networking/GameServer.cs | 13 +- .../BarotraumaServer/WindowsServer.csproj | 4 + .../SharedSource/DebugConsole.cs | 5 +- .../GameSession/GameModes/GameMode.cs | 116 ++++----- 11 files changed, 451 insertions(+), 63 deletions(-) create mode 100644 Barotrauma/BarotraumaServer/ServerSource/Lua/LuaCustomConverters.cs create mode 100644 Barotrauma/BarotraumaServer/ServerSource/Lua/LuaScriptLoader.cs create mode 100644 Barotrauma/BarotraumaServer/ServerSource/Lua/LuaSetup.cs diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index 619c4ffc8..fc4f285b7 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -123,6 +123,7 @@ + diff --git a/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs b/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs index 563e0195d..09328fa90 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs @@ -734,7 +734,7 @@ namespace Barotrauma revokedCommands.Add(matchingCommand); } } - } + } client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Except(revokedCommands).ToList()); GameMain.Server.UpdateClientPermissions(client); @@ -899,9 +899,9 @@ namespace Barotrauma { if (GameMain.Server?.KarmaManager == null) { return; } GameMain.Server.KarmaManager.TestMode = !GameMain.Server.KarmaManager.TestMode; - NewMessage(GameMain.Server.KarmaManager.TestMode ? + NewMessage(GameMain.Server.KarmaManager.TestMode ? $"Karma test mode enabled by {client.Name}." : - $"Karma test mode disabled by {client.Name}.", + $"Karma test mode disabled by {client.Name}.", Color.LightGreen); GameMain.Server.SendDirectChatMessage( GameMain.Server.KarmaManager.TestMode ? "Karma test mode enabled." : "Karma test mode disabled.", @@ -1205,7 +1205,7 @@ namespace Barotrauma (Client client, Vector2 cursorPos, string[] args) => { string text = string.Join(" ", args); - text = client.Name+": " + text; + text = client.Name + ": " + text; if (GameMain.Server.OwnerConnection != null && client.Connection == GameMain.Server.OwnerConnection) { @@ -1242,6 +1242,18 @@ namespace Barotrauma GameMain.NetLobbyScreen.LevelSeed = string.Join(" ", args); })); + + commands.Add(new Command("lua", "lua: runs a string", (string[] args) => + { + GameMain.Lua.DoString(string.Join(" ", args)); + })); + + commands.Add(new Command("reloadlua", "reloads lua", (string[] args) => + { + GameMain.Lua = new LuaSetup(); + })); + + commands.Add(new Command("randomizeseed", "randomizeseed: Toggles level seed randomization on/off.", (string[] args) => { GameMain.Server.ServerSettings.RandomizeSeed = !GameMain.Server.ServerSettings.RandomizeSeed; diff --git a/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs b/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs index 6abe50855..51451964b 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/GameMain.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Xml.Linq; +using MoonSharp.Interpreter; namespace Barotrauma { @@ -20,6 +21,7 @@ namespace Barotrauma public static World World; public static GameSettings Config; + public static LuaSetup Lua; public static GameServer Server; public static NetworkMember NetworkMember @@ -131,6 +133,8 @@ namespace Barotrauma NetLobbyScreen = new NetLobbyScreen(); CheckContentPackage(); + + Lua = new LuaSetup(); } @@ -357,6 +361,8 @@ namespace Barotrauma TaskPool.Update(); CoroutineManager.Update((float)Timing.Step, (float)Timing.Step); + GameMain.Lua.hook.Call("think", new DynValue[] { DynValue.NewNumber(elapsedTime) }); + Timing.Accumulator -= Timing.Step; } diff --git a/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaCustomConverters.cs b/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaCustomConverters.cs new file mode 100644 index 000000000..8db9b3806 --- /dev/null +++ b/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaCustomConverters.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MoonSharp.Interpreter; +using Microsoft.Xna.Framework; + +namespace Barotrauma +{ + + public static class LuaCustomConverters + { + + public static void RegisterAll() + { + + // Vector 2 + + Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(Vector2), + dynVal => { + Table table = dynVal.Table; + float x = (float)((Double)table[1]); + float y = (float)((Double)table[2]); + return new Vector2(x, y); + } + ); + Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion( + (script, vector) => { + DynValue x = DynValue.NewNumber((double)vector.X); + DynValue y = DynValue.NewNumber((double)vector.Y); + DynValue dynVal = DynValue.NewTable(script, new DynValue[] { x, y }); + return dynVal; + } + ); + + // Vector3 + + Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(Vector3), + dynVal => { + Table table = dynVal.Table; + float x = (float)((Double)table[1]); + float y = (float)((Double)table[2]); + float z = (float)((Double)table[3]); + return new Vector3(x, y, z); + } + ); + Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion( + (script, vector) => { + DynValue x = DynValue.NewNumber((double)vector.X); + DynValue y = DynValue.NewNumber((double)vector.Y); + DynValue z = DynValue.NewNumber((double)vector.Z); + DynValue dynVal = DynValue.NewTable(script, new DynValue[] { x, y, z }); + return dynVal; + } + ); + + } + + } +} diff --git a/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaScriptLoader.cs b/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaScriptLoader.cs new file mode 100644 index 000000000..461ad7777 --- /dev/null +++ b/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaScriptLoader.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using MoonSharp.Interpreter; +using MoonSharp.Interpreter.Loaders; + +namespace Barotrauma +{ + public class LuaScriptLoader : ScriptLoaderBase + { + public override object LoadFile(string file, Table globalContext) + { + return File.ReadAllText(file); + } + + public override bool ScriptFileExists(string file) + { + return File.Exists(file); + } + + public void RunFolder(string folder, Script script) + { + foreach(var str in DirSearch(folder)) + { + script.DoFile(str.Replace("\\", "/")); // i hate windows + } + } + + static string[] DirSearch(string sDir) + { + List files = new List(); + + try + { + foreach (string f in Directory.GetFiles(sDir)) + { + files.Add(f); + } + + foreach (string d in Directory.GetDirectories(sDir)) + { + foreach (string f in Directory.GetFiles(d)) + { + files.Add(f); + } + DirSearch(d); + } + } + catch (System.Exception excpt) + { + Console.WriteLine(excpt.Message); + } + + return files.ToArray(); + } + + + + + } +} diff --git a/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaSetup.cs b/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaSetup.cs new file mode 100644 index 000000000..420dbeacf --- /dev/null +++ b/Barotrauma/BarotraumaServer/ServerSource/Lua/LuaSetup.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Barotrauma.Networking; +using MoonSharp.Interpreter; +using Microsoft.Xna.Framework; + +namespace Barotrauma +{ + class LuaSetup + { + + public Script lua; + public Hook hook; + + + public void DoString(string code) + { + try + { + lua.DoString(code); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private class Player + { + + public static List GetAllCharacters() + { + List values = new List(); + + foreach (Character ch in Character.CharacterList) + { + values.Add(UserData.Create(ch)); + } + + return values; + } + + public static List GetAllClients() + { + List values = new List(); + + foreach (Client ch in GameMain.Server.ConnectedClients) + { + values.Add(UserData.Create(ch)); + } + + return values; + } + + public static void SetClientCharacter(Client client, Character character) + { + GameMain.Server.SetClientCharacter(client, character); + } + + public static void Kick(Client client, string reason="") + { + GameMain.Server.KickClient(client.Connection, reason); + } + + public static void Ban(Client client, string reason = "", bool range = false, float seconds=-1) + { + if(seconds == -1) + { + GameMain.Server.BanClient(client, reason, range, null); + } + else + { + GameMain.Server.BanClient(client, reason, range, TimeSpan.FromSeconds(seconds)); + } + + } + + public static void StartGame() + { + GameMain.Server.StartGame(); + } + } + + private class Game + { + public static void SendMessage(string msg, int messageType = 0, Client sender = null, Character character = null) + { + GameMain.Server.SendChatMessage(msg, (ChatMessageType)messageType, sender, character); + } + + public static void Explode(Vector2 pos, float range=100, float force=30, float damage=30, float structureDamage=30, float itemDamage=30, float empStrength=0, float ballastFloraStrength=0) + { + new Explosion(range, force, damage, structureDamage, itemDamage, empStrength, ballastFloraStrength).Explode(pos, null); + } + + public static string Spawn(string name, Vector2 pos) + { + string error; + DebugConsole.SpawnCharacter(new string[] {name, "cursor"}, pos, out error); + return error; + } + + public static string SpawnItem(string name, Vector2 pos, bool inventory = false, Character character=null) + { + string error; + DebugConsole.SpawnItem(new string[] { name, inventory ? "inventory" : "cursor" }, pos, character, out error); + return error; + } + } + + + // hooks: + // chatMessage + // think + // update + // clientConnected + // clientDisconnected + // roundStart + // roundEnd + + public class Hook + { + public Script env; + + public Hook(Script e) + { + env = e; + } + + public class HookFunction + { + public string name; + public string hookName; + public DynValue function; + + public HookFunction(string n, string hn, DynValue func) + { + name = n; + hookName = hn; + function = func; + } + } + + public List hookFunctions = new List(); + + public void Add(string name, string hookName, DynValue function) + { + foreach (HookFunction hf in hookFunctions) + { + if(hf.hookName == hookName && hf.name == name) + { + hf.function = function; + + return; + } + } + + hookFunctions.Add(new HookFunction(name, hookName, function)); + } + + public void Call(string name, DynValue[] args) + { + foreach(HookFunction hf in hookFunctions) + { + if (hf.name == name) + { + try + { + env.Call(hf.function, args); + }catch(Exception e) + { + Console.WriteLine(e.ToString()); + } + } + } + } + } + + public LuaSetup() + { + + Console.WriteLine("Lua!"); + + LuaCustomConverters.RegisterAll(); + + LuaScriptLoader luaScriptLoader = new LuaScriptLoader(); + + //UserData.RegisterAssembly(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + UserData.RegisterType(); + + lua = new Script(CoreModules.Preset_SoftSandbox); + + lua.Options.ScriptLoader = luaScriptLoader; + + hook = new Hook(lua); + + lua.Globals["Player"] = new Player(); + lua.Globals["Game"] = new Game(); + lua.Globals["Hook"] = hook; + + + luaScriptLoader.RunFolder("Lua/autorun", lua); + + + } + + } + + + +} + + diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs index dfcda4b3c..1370f16fe 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/ChatMessage.cs @@ -1,6 +1,7 @@ using Microsoft.Xna.Framework; using System; using System.Text; +using MoonSharp.Interpreter; namespace Barotrauma.Networking { @@ -222,6 +223,11 @@ namespace Barotrauma.Networking { GameMain.Server.SendChatMessage(txt, null, c); } + + + GameMain.Lua.hook.Call("chatMessage", new DynValue[] { DynValue.NewString(txt), UserData.Create(c) }); + + } public int EstimateLengthBytesServer(Client c) diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs index 2f4426c74..288780f32 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs @@ -309,7 +309,10 @@ namespace Barotrauma.Networking SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient); } - SendChatMessage($"ServerMessage.JoinedServer~[client]={ClientLogName(newClient)}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined); + GameMain.Lua.hook.Call("clientConnected", new MoonSharp.Interpreter.DynValue[] { MoonSharp.Interpreter.UserData.Create(newClient) }); + + + SendChatMessage($"ServerMessage.JoinedServer~[client]={clName}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined); serverSettings.ServerDetailsChanged = true; if (previousPlayer != null && previousPlayer.Name != newClient.Name) @@ -2410,6 +2413,9 @@ namespace Barotrauma.Networking Log("Round started.", ServerLog.MessageType.ServerMessage); + GameMain.Lua.hook.Call("roundStart", new MoonSharp.Interpreter.DynValue[] { }); + + gameStarted = true; initiatedStartGame = false; GameMain.ResetFrameTime(); @@ -2535,6 +2541,9 @@ namespace Barotrauma.Networking Log("Ending the round...", ServerLog.MessageType.ServerMessage); } + GameMain.Lua.hook.Call("roundEnd", new MoonSharp.Interpreter.DynValue[] { }); + + string endMessage = TextManager.FormatServerMessage("RoundSummaryRoundHasEnded"); var traitorResults = TraitorManager?.GetEndResults() ?? new List(); @@ -2828,6 +2837,8 @@ namespace Barotrauma.Networking { if (client == null) return; + GameMain.Lua.hook.Call("clientDisconnected", new MoonSharp.Interpreter.DynValue[] { MoonSharp.Interpreter.UserData.Create(client) }); + if (gameStarted && client.Character != null) { client.Character.ClientDisconnected = true; diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index b3f2ff36d..2d0a14086 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -79,6 +79,10 @@ + + + + diff --git a/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs b/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs index 36daaf126..8e2d17022 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs @@ -37,6 +37,7 @@ namespace Barotrauma static partial class DebugConsole { + public partial class Command { public readonly string[] names; @@ -1821,7 +1822,7 @@ namespace Barotrauma return null; } - private static void SpawnCharacter(string[] args, Vector2 cursorWorldPos, out string errorMsg) + public static void SpawnCharacter(string[] args, Vector2 cursorWorldPos, out string errorMsg) { errorMsg = ""; if (args.Length == 0) { return; } @@ -1914,7 +1915,7 @@ namespace Barotrauma } } - private static void SpawnItem(string[] args, Vector2 cursorPos, Character controlledCharacter, out string errorMsg) + public static void SpawnItem(string[] args, Vector2 cursorPos, Character controlledCharacter, out string errorMsg) { errorMsg = ""; if (args.Length < 1) return; diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/GameMode.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/GameMode.cs index 1061e9754..dfc8516ab 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/GameMode.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/GameMode.cs @@ -1,79 +1,83 @@ using System; using System.Collections.Generic; -using System.Linq; +#if SERVER +using MoonSharp.Interpreter; +#endif namespace Barotrauma { - partial class GameMode - { - public static List PresetList = new List(); + partial class GameMode + { + public static List PresetList = new List(); - protected DateTime startTime; - - protected GameModePreset preset; - - public CrewManager CrewManager - { - get { return GameMain.GameSession?.CrewManager; } - } + protected DateTime startTime; - public virtual IEnumerable Missions - { - get { return Enumerable.Empty(); } - } + protected GameModePreset preset; - public bool IsSinglePlayer - { - get { return preset.IsSinglePlayer; } - } + public CrewManager CrewManager + { + get { return GameMain.GameSession?.CrewManager; } + } - public string Name - { - get { return preset.Name; } - } + public virtual Mission Mission + { + get { return null; } + } - public virtual bool Paused - { - get { return false; } - } + public bool IsSinglePlayer + { + get { return preset.IsSinglePlayer; } + } - public virtual void UpdateWhilePaused(float deltaTime) { } + public string Name + { + get { return preset.Name; } + } - public GameModePreset Preset - { - get { return preset; } - } + public virtual bool Paused + { + get { return false; } + } - public GameMode(GameModePreset preset) - { - this.preset = preset; - } + public virtual void UpdateWhilePaused(float deltaTime) { } - public virtual void Start() - { - startTime = DateTime.Now; - } + public GameModePreset Preset + { + get { return preset; } + } - public virtual void ShowStartMessage() { } + public GameMode(GameModePreset preset) + { + this.preset = preset; + } - public virtual void AddExtraMissions(LevelData levelData) { } - - public virtual void AddToGUIUpdateList() - { + public virtual void Start() + { + startTime = DateTime.Now; + } + + public virtual void ShowStartMessage() { } + + public virtual void AddToGUIUpdateList() + { #if CLIENT GameMain.GameSession?.CrewManager.AddToGUIUpdateList(); #endif - } + } - public virtual void Update(float deltaTime) - { - CrewManager?.Update(deltaTime); - } + public virtual void Update(float deltaTime) + { + CrewManager?.Update(deltaTime); - public virtual void End(CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None) - { - } +#if SERVER + GameMain.Lua.hook.Call("update", new DynValue[] { DynValue.NewNumber(deltaTime) }); +#endif + } - public virtual void Remove() { } - } + public virtual void End(CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None) + { + } + + public virtual void Remove() { } + } }