Refactor and fix #56
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public abstract class ACsMod : IDisposable
|
||||
{
|
||||
private static List<ACsMod> mods = new List<ACsMod>();
|
||||
public static List<ACsMod> LoadedMods { get => mods; }
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
public ACsMod()
|
||||
{
|
||||
IsDisposed = false;
|
||||
LoadedMods.Add(this);
|
||||
Start();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Stop();
|
||||
LoadedMods.Remove(this);
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
// TODO: some hooks
|
||||
|
||||
/// Mod initialization
|
||||
public abstract void Start();
|
||||
/// Error or client exit
|
||||
public abstract void Stop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Barotrauma {
|
||||
class CsScriptFilter
|
||||
{
|
||||
private const bool useWhitelist = false;
|
||||
|
||||
private static string[] typesPermited = new string[] {
|
||||
// Basics
|
||||
"System.Runtime.CompilerServices.CompilationRelaxationsAttribute",
|
||||
"System.Runtime.CompilerServices.RuntimeCompatibilityAttribute",
|
||||
"System.Diagnostics.DebuggableAttribute",
|
||||
"System.Object",
|
||||
"System.String",
|
||||
"System.Collections",
|
||||
// Some roslyn magic
|
||||
".DebuggingModes",
|
||||
// Barotrauma
|
||||
"Barotrauma",
|
||||
};
|
||||
private static string[] typessProhibited = new string[] {
|
||||
//"System.Reflection",
|
||||
"System.IO",
|
||||
};
|
||||
public static bool IsTypeAllowed(string usingName)
|
||||
{
|
||||
if (useWhitelist && !typesPermited.Any(u => u.StartsWith(usingName))) return false;
|
||||
if (typessProhibited.Any(u => u.StartsWith(usingName))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string FilterSyntaxTree(CSharpSyntaxTree tree)
|
||||
{
|
||||
if (tree == null) throw new ArgumentNullException("Syntax tree must not be null.");
|
||||
|
||||
{ // Disallow top-level statements
|
||||
var nodeCheck = tree.GetRoot().DescendantNodes();
|
||||
|
||||
var tlStatements = nodeCheck.Where(n => n is GlobalStatementSyntax).ToList();
|
||||
if (tlStatements.Count > 0)
|
||||
{
|
||||
string errStr = "Cmopilation Error:";
|
||||
foreach (var tls in tlStatements) tls.GetDiagnostics().ToList().ForEach(d => errStr += $"\n {d.ToString()}");
|
||||
return errStr;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string FilterMetadata(MetadataReader reader)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException("Metadata Reader must not be null.");
|
||||
|
||||
var conflictingTypes = new List<string>();
|
||||
reader.TypeReferences.ToList().ForEach(t =>
|
||||
{
|
||||
var tRef = reader.GetTypeReference(t);
|
||||
var typeName = $"{reader.GetString(tRef.Namespace)}.{reader.GetString(tRef.Name)}";
|
||||
if (!IsTypeAllowed(typeName)) conflictingTypes.Add(typeName);
|
||||
});
|
||||
|
||||
if (conflictingTypes.Count > 0)
|
||||
{
|
||||
string errStr = "Metadata Error:";
|
||||
conflictingTypes.ForEach(t => errStr += $"\n Usage of type '{t}' in mods is prohibited.");
|
||||
return errStr;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
using System.Reflection;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Runtime.Loader;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class CsScriptLoader : AssemblyLoadContext
|
||||
{
|
||||
public LuaCsSetup setup;
|
||||
private List<MetadataReference> defaultReferences;
|
||||
private List<SyntaxTree> syntaxTrees;
|
||||
public Assembly Assembly { get; private set; }
|
||||
|
||||
public CsScriptLoader(LuaCsSetup setup)
|
||||
{
|
||||
this.setup = setup;
|
||||
|
||||
defaultReferences = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")))
|
||||
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
||||
.ToList();
|
||||
|
||||
syntaxTrees = new List<SyntaxTree>();
|
||||
Assembly = null;
|
||||
}
|
||||
|
||||
public void SearchFolders()
|
||||
{
|
||||
foreach(ContentPackage cp in ContentPackageManager.EnabledPackages.All)
|
||||
{
|
||||
var path = Path.GetDirectoryName(cp.Path);
|
||||
RunFolder(path);
|
||||
}
|
||||
}
|
||||
|
||||
private void RunFolder(string folder)
|
||||
{
|
||||
var scriptFiles = new List<string>();
|
||||
foreach (var str in DirSearch(folder))
|
||||
{
|
||||
var s = str.Replace("\\", "/");
|
||||
|
||||
if (s.EndsWith(".cs") && LuaCsFile.IsPathAllowedCsException(s)) scriptFiles.Add(s);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (scriptFiles.Count <= 0) return;
|
||||
|
||||
// Check file content for prohibited stuff
|
||||
foreach (var file in scriptFiles)
|
||||
{
|
||||
var tree = SyntaxFactory.ParseSyntaxTree(File.ReadAllText(file), CSharpParseOptions.Default, file);
|
||||
var error = CsScriptFilter.FilterSyntaxTree(tree as CSharpSyntaxTree);
|
||||
if (error != null) throw new Exception(error);
|
||||
|
||||
syntaxTrees.Add(tree);
|
||||
}
|
||||
}
|
||||
catch (CompilationErrorException ex)
|
||||
{
|
||||
string errStr = "Cmopilation Error in '" + folder + "':";
|
||||
foreach (var diag in ex.Diagnostics)
|
||||
{
|
||||
errStr += "\n" + diag.ToString();
|
||||
}
|
||||
LuaCsSetup.PrintCsMessage(errStr);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage("Error loading '" + folder + "':\n" + ex.Message + "\n" + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Type> Compile()
|
||||
{
|
||||
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
||||
.WithMetadataImportOptions(MetadataImportOptions.All)
|
||||
.WithOptimizationLevel(OptimizationLevel.Release)
|
||||
.WithAllowUnsafe(false);
|
||||
var compilation = CSharpCompilation.Create("NetScriptAssembly",syntaxTrees, defaultReferences, options);
|
||||
|
||||
using (var mem = new MemoryStream())
|
||||
{
|
||||
var result = compilation.Emit(mem);
|
||||
if (!result.Success)
|
||||
{
|
||||
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(d => d.IsWarningAsError || d.Severity == DiagnosticSeverity.Error);
|
||||
|
||||
string errStr = "NET MODS NOT LOADED | Mod cmopilation errors:";
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
errStr = $"\n{diagnostic}";
|
||||
LuaCsSetup.PrintCsMessage(errStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
var errStr = CsScriptFilter.FilterMetadata(new PEReader(mem).GetMetadataReader());
|
||||
if (errStr == null)
|
||||
{
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
Assembly = LoadFromStream(mem);
|
||||
}
|
||||
else LuaCsSetup.PrintCsMessage(errStr);
|
||||
}
|
||||
}
|
||||
syntaxTrees.Clear();
|
||||
|
||||
if (Assembly != null)
|
||||
return Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(ACsMod))).ToList();
|
||||
else
|
||||
throw new Exception("Unable to create net mods assembly.");
|
||||
}
|
||||
|
||||
private static string[] DirSearch(string sDir)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (string f in Directory.GetFiles(sDir))
|
||||
{
|
||||
files.Add(f);
|
||||
}
|
||||
|
||||
foreach (string d in Directory.GetDirectories(sDir))
|
||||
{
|
||||
files.AddRange(DirSearch(d));
|
||||
}
|
||||
}
|
||||
catch (System.Exception excpt)
|
||||
{
|
||||
Console.WriteLine(excpt.Message);
|
||||
}
|
||||
|
||||
return files.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MoonSharp.Interpreter;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class Client
|
||||
{
|
||||
public static List<Client> ClientList
|
||||
{
|
||||
get
|
||||
{
|
||||
#if SERVER
|
||||
return GameMain.Server.ConnectedClients;
|
||||
#else
|
||||
return GameMain.Client.ConnectedClients;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
using Barotrauma.Networking;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
|
||||
partial class Character
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
partial class Item
|
||||
{
|
||||
public object GetComponentString(string component)
|
||||
{
|
||||
Type type = Type.GetType("Barotrauma.Items.Components." + component);
|
||||
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
MethodInfo method = typeof(Item).GetMethod(nameof(Item.GetComponent));
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(this, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
partial class ItemPrefab
|
||||
{
|
||||
|
||||
public static ItemPrefab GetItemPrefab(string itemNameOrId)
|
||||
{
|
||||
ItemPrefab itemPrefab =
|
||||
(MapEntityPrefab.Find(itemNameOrId, identifier: null, showErrorMessages: false) ??
|
||||
MapEntityPrefab.Find(null, identifier: itemNameOrId, showErrorMessages: false)) as ItemPrefab;
|
||||
|
||||
return itemPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
abstract partial class MapEntity
|
||||
{
|
||||
public void AddLinked(MapEntity entity)
|
||||
{
|
||||
linkedTo.Add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
using Barotrauma.Networking;
|
||||
|
||||
partial class CustomInterface
|
||||
{
|
||||
}
|
||||
|
||||
partial struct Signal
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaGame
|
||||
{
|
||||
public bool IsSingleplayer => GameMain.IsSingleplayer;
|
||||
public bool IsMultiplayer => GameMain.IsMultiplayer;
|
||||
|
||||
#if CLIENT
|
||||
public bool Paused => GameMain.Instance?.Paused == true;
|
||||
|
||||
public byte MyID => GameMain.Client.ID;
|
||||
|
||||
|
||||
public ChatBox ChatBox
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GameMain.IsSingleplayer)
|
||||
return GameMain.GameSession.CrewManager.ChatBox;
|
||||
else
|
||||
return GameMain.Client.ChatBox;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
public bool IsDedicated
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server.ServerPeer is LidgrenServerPeer;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerSettings ServerSettings => GameMain.Server.ServerSettings;
|
||||
#endif
|
||||
|
||||
public DynValue Settings;
|
||||
|
||||
|
||||
public bool allowWifiChat = false;
|
||||
public bool overrideTraitors = false;
|
||||
public bool overrideRespawnSub = false;
|
||||
public bool overrideSignalRadio = false;
|
||||
public bool disableSpamFilter = false;
|
||||
public bool disableDisconnectCharacter = false;
|
||||
public bool enableControlHusk = false;
|
||||
|
||||
public int mapEntityUpdateInterval
|
||||
{
|
||||
get { return MapEntity.MapEntityUpdateInterval; }
|
||||
set { MapEntity.MapEntityUpdateInterval = value; }
|
||||
}
|
||||
|
||||
public int gapUpdateInterval
|
||||
{
|
||||
get { return MapEntity.GapUpdateInterval; }
|
||||
set { MapEntity.GapUpdateInterval = value; }
|
||||
}
|
||||
|
||||
public int characterUpdateInterval
|
||||
{
|
||||
get { return Character.CharacterUpdateInterval; }
|
||||
set { Character.CharacterUpdateInterval = value; }
|
||||
}
|
||||
|
||||
public HashSet<Item> updatePriorityItems = new HashSet<Item>();
|
||||
public HashSet<Character> updatePriorityCharacters = new HashSet<Character>();
|
||||
|
||||
public void AddPriorityItem(Item item)
|
||||
{
|
||||
updatePriorityItems.Add(item);
|
||||
}
|
||||
|
||||
public void RemovePriorityItem(Item item)
|
||||
{
|
||||
updatePriorityItems.Remove(item);
|
||||
}
|
||||
|
||||
public void ClearPriorityItem()
|
||||
{
|
||||
updatePriorityItems.Clear();
|
||||
}
|
||||
|
||||
public void AddPriorityCharacter(Character character)
|
||||
{
|
||||
updatePriorityCharacters.Add(character);
|
||||
}
|
||||
|
||||
public void RemovePriorityCharacter(Character character)
|
||||
{
|
||||
updatePriorityCharacters.Remove(character);
|
||||
}
|
||||
|
||||
public void ClearPriorityCharacter()
|
||||
{
|
||||
updatePriorityCharacters.Clear();
|
||||
}
|
||||
|
||||
public bool RoundStarted
|
||||
{
|
||||
|
||||
get
|
||||
{
|
||||
#if SERVER
|
||||
return GameMain.Server.GameStarted;
|
||||
#else
|
||||
return GameMain.Client.GameStarted;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public GameSession GameSession
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.GameSession;
|
||||
}
|
||||
}
|
||||
|
||||
public NetLobbyScreen NetLobbyScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.NetLobbyScreen;
|
||||
}
|
||||
}
|
||||
|
||||
public GameScreen GameScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.GameScreen;
|
||||
}
|
||||
}
|
||||
|
||||
public World World
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.World;
|
||||
}
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
public ServerPeer Peer
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server.ServerPeer;
|
||||
}
|
||||
}
|
||||
#else
|
||||
public ClientPeer Peer
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Client.ClientPeer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public LuaGame()
|
||||
{
|
||||
LuaUserData.MakeFieldAccessible(UserData.RegisterType(typeof(GameSettings)), "currentConfig");
|
||||
Settings = UserData.CreateStatic(typeof(GameSettings));
|
||||
}
|
||||
|
||||
public void OverrideTraitors(bool o)
|
||||
{
|
||||
overrideTraitors = o;
|
||||
}
|
||||
|
||||
public void OverrideRespawnSub(bool o)
|
||||
{
|
||||
overrideRespawnSub = o;
|
||||
}
|
||||
|
||||
public void AllowWifiChat(bool o)
|
||||
{
|
||||
allowWifiChat = o;
|
||||
}
|
||||
|
||||
public void OverrideSignalRadio(bool o)
|
||||
{
|
||||
overrideSignalRadio = o;
|
||||
}
|
||||
|
||||
public void DisableSpamFilter(bool o)
|
||||
{
|
||||
disableSpamFilter = o;
|
||||
}
|
||||
|
||||
public void DisableDisconnectCharacter(bool o)
|
||||
{
|
||||
disableDisconnectCharacter = o;
|
||||
}
|
||||
|
||||
|
||||
public void EnableControlHusk(bool o)
|
||||
{
|
||||
enableControlHusk = o;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
public static ContentPackage[] GetEnabledContentPackages()
|
||||
{
|
||||
return ContentPackageManager.EnabledPackages.All.ToArray();
|
||||
}
|
||||
|
||||
public static ItemPrefab GetItemPrefab(string itemNameOrId)
|
||||
{
|
||||
ItemPrefab itemPrefab =
|
||||
(MapEntityPrefab.Find(itemNameOrId, identifier: null, showErrorMessages: false) ??
|
||||
MapEntityPrefab.Find(null, identifier: itemNameOrId, showErrorMessages: false)) as ItemPrefab;
|
||||
|
||||
return itemPrefab;
|
||||
}
|
||||
|
||||
public static Submarine GetRespawnSub()
|
||||
{
|
||||
#if SERVER
|
||||
if (GameMain.Server.RespawnManager == null)
|
||||
return null;
|
||||
return GameMain.Server.RespawnManager.RespawnShuttle;
|
||||
#else
|
||||
if (GameMain.Client.RespawnManager == null)
|
||||
return null;
|
||||
return GameMain.Client.RespawnManager.RespawnShuttle;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Items.Components.Steering GetSubmarineSteering(Submarine sub)
|
||||
{
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != sub) continue;
|
||||
|
||||
var steering = item.GetComponent<Items.Components.Steering>();
|
||||
if (steering != null)
|
||||
{
|
||||
return steering;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static WifiComponent GetWifiComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<WifiComponent>();
|
||||
}
|
||||
|
||||
public static LightComponent GetLightComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<LightComponent>();
|
||||
}
|
||||
|
||||
public static CustomInterface GetCustomInterface(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<CustomInterface>();
|
||||
}
|
||||
|
||||
public static Fabricator GetFabricatorComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<Fabricator>();
|
||||
}
|
||||
|
||||
public static Holdable GetHoldableComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<Holdable>();
|
||||
}
|
||||
|
||||
public static void ExecuteCommand(string command)
|
||||
{
|
||||
DebugConsole.ExecuteCommand(command);
|
||||
}
|
||||
|
||||
public static Signal CreateSignal(string value, int stepsTaken = 1, Character sender = null, Item source = null, float power = 0, float strength = 1)
|
||||
{
|
||||
return new Signal(value, stepsTaken, sender, source, power, strength);
|
||||
}
|
||||
|
||||
private List<DebugConsole.Command> luaAddedCommand = new List<DebugConsole.Command>();
|
||||
|
||||
public void RemoveCommand(string name)
|
||||
{
|
||||
for (var i = 0; i < DebugConsole.Commands.Count; i++)
|
||||
{
|
||||
foreach (var cmdname in DebugConsole.Commands[i].names)
|
||||
{
|
||||
if (cmdname == name)
|
||||
{
|
||||
luaAddedCommand.Remove(DebugConsole.Commands[i]);
|
||||
DebugConsole.Commands.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCommand(string name, string help, CsAction onExecute, CsFunc getValidArgs = null, bool isCheat = false)
|
||||
{
|
||||
var cmd = new DebugConsole.Command(name, help, (string[] arg1) => { onExecute(arg1); },
|
||||
() =>
|
||||
{
|
||||
if (getValidArgs == null) return null;
|
||||
var obj = getValidArgs();
|
||||
if (obj is LuaResult res) obj = res.Object();
|
||||
if (obj is string[][]) return (string[][])obj;
|
||||
return null;
|
||||
}, isCheat);
|
||||
|
||||
luaAddedCommand.Add(cmd);
|
||||
DebugConsole.Commands.Add(cmd);
|
||||
|
||||
#if SERVER
|
||||
foreach (var client in GameMain.Server.ConnectedClients) {
|
||||
var index = client.PermittedConsoleCommands.FindIndex((pc) => pc.names[0] == cmd.names[0]);
|
||||
if (index > -1) {
|
||||
client.PermittedConsoleCommands[index] = cmd;
|
||||
}
|
||||
}
|
||||
foreach (var permissions in GameMain.Server.ServerSettings.ClientPermissions) {
|
||||
var index = permissions.PermittedCommands.FindIndex((pc) => pc.names[0] == cmd.names[0]);
|
||||
if (index > -1) {
|
||||
permissions.PermittedCommands[index] = cmd;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public List<DebugConsole.Command> Commands => DebugConsole.Commands;
|
||||
|
||||
public void AssignOnExecute(string names, object onExecute) => DebugConsole.AssignOnExecute(names, (string[] a) => { GameMain.LuaCs.CallLuaFunction(onExecute, new object[] { a }); });
|
||||
|
||||
|
||||
#if SERVER
|
||||
|
||||
public static void SendMessage(string msg, ChatMessageType? messageType = null, Client sender = null, Character character = null)
|
||||
{
|
||||
GameMain.Server.SendChatMessage(msg, messageType, sender, character);
|
||||
}
|
||||
|
||||
public static void SendMessage(string msg, int messageType, Client sender = null, Character character = null)
|
||||
{
|
||||
GameMain.Server.SendChatMessage(msg, (ChatMessageType)messageType, sender, character);
|
||||
}
|
||||
|
||||
public static void SendTraitorMessage(Client client, string msg, Identifier missionid, TraitorMessageType type)
|
||||
{
|
||||
GameMain.Server.SendTraitorMessage(client, msg, missionid, type);
|
||||
}
|
||||
|
||||
public static void SendDirectChatMessage(string sendername, string text, Character sender, ChatMessageType messageType = ChatMessageType.Private, Client client = null, string iconStyle = "")
|
||||
{
|
||||
|
||||
ChatMessage cm = ChatMessage.Create(sendername, text, messageType, sender, client);
|
||||
cm.IconStyle = iconStyle;
|
||||
|
||||
GameMain.Server.SendDirectChatMessage(cm, client);
|
||||
|
||||
}
|
||||
|
||||
public static void SendDirectChatMessage(ChatMessage chatMessage, Client client)
|
||||
{
|
||||
GameMain.Server.SendDirectChatMessage(chatMessage, client);
|
||||
}
|
||||
|
||||
public static void Log(string message, ServerLog.MessageType type)
|
||||
{
|
||||
GameServer.Log(message, type);
|
||||
}
|
||||
|
||||
public static void DispatchRespawnSub()
|
||||
{
|
||||
GameMain.Server.RespawnManager.DispatchShuttle();
|
||||
}
|
||||
|
||||
public static void StartGame()
|
||||
{
|
||||
GameMain.Server.StartGame();
|
||||
}
|
||||
|
||||
public static void EndGame()
|
||||
{
|
||||
GameMain.Server.EndGame();
|
||||
}
|
||||
|
||||
public void AssignOnClientRequestExecute(string names, object onExecute) => DebugConsole.AssignOnClientRequestExecute(names, (Client a, Vector2 b, string[] c) => { GameMain.LuaCs.CallLuaFunction(onExecute, new object[] { a, b, c }); });
|
||||
|
||||
#endif
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
mapEntityUpdateInterval = 1;
|
||||
gapUpdateInterval = 4;
|
||||
characterUpdateInterval = 1;
|
||||
|
||||
foreach (var cmd in luaAddedCommand)
|
||||
{
|
||||
DebugConsole.Commands.Remove(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public class LuaByte
|
||||
{
|
||||
public byte Value;
|
||||
|
||||
public LuaByte(byte v)
|
||||
{
|
||||
Value = v;
|
||||
}
|
||||
|
||||
public static implicit operator byte(LuaByte lb) => lb.Value;
|
||||
}
|
||||
|
||||
public class LuaUShort
|
||||
{
|
||||
public ushort Value;
|
||||
|
||||
public LuaUShort(ushort v)
|
||||
{
|
||||
Value = v;
|
||||
}
|
||||
|
||||
public static implicit operator ushort(LuaUShort lb) => lb.Value;
|
||||
}
|
||||
|
||||
public class LuaFloat
|
||||
{
|
||||
public float Value;
|
||||
|
||||
public LuaFloat(float v)
|
||||
{
|
||||
Value = v;
|
||||
}
|
||||
|
||||
public static implicit operator float(LuaFloat lb) => lb.Value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaUserData
|
||||
{
|
||||
public static Type GetType(string typeName)
|
||||
{
|
||||
var type = Type.GetType(typeName);
|
||||
if (type != null) return type;
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
type = a.GetType(typeName);
|
||||
if (type != null)
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IUserDataDescriptor RegisterType(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to register a type that doesn't exist: {typeName}."));
|
||||
return null;
|
||||
}
|
||||
|
||||
return UserData.RegisterType(type);
|
||||
}
|
||||
|
||||
public static void UnregisterType(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to unregister a type that doesn't exist: {typeName}."));
|
||||
return;
|
||||
}
|
||||
|
||||
UserData.UnregisterType(type);
|
||||
}
|
||||
public static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
|
||||
Type genericType = type.MakeGenericType(typeArguements);
|
||||
return UserData.RegisterType(genericType);
|
||||
}
|
||||
|
||||
public static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
|
||||
Type genericType = type.MakeGenericType(typeArguements);
|
||||
UserData.UnregisterType(genericType);
|
||||
}
|
||||
|
||||
private static bool IsType<T>(object obj) { return obj is T; }
|
||||
|
||||
public static bool IsTargetType(object obj, string typeName)
|
||||
{
|
||||
var type = GetType(typeName);
|
||||
MethodInfo method = typeof(LuaUserData).GetMethod(nameof(IsType), BindingFlags.NonPublic | BindingFlags.Static);
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return (bool)generic.Invoke(null, new object[] { obj });
|
||||
}
|
||||
|
||||
public static object CreateStatic(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to create a static userdata of a type that doesn't exist: {typeName}."));
|
||||
return null;
|
||||
}
|
||||
|
||||
MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(null, null);
|
||||
}
|
||||
|
||||
public static object CreateEnumTable(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to create an enum table with a type that doesn't exist:: {typeName}."));
|
||||
return null;
|
||||
}
|
||||
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
foreach (var value in Enum.GetValues(type))
|
||||
{
|
||||
string name = Enum.GetName(type, value);
|
||||
|
||||
result[name] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static FieldInfo FindFieldRecursively(Type type, string fieldName)
|
||||
{
|
||||
var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
if (field == null && type.BaseType != null)
|
||||
{
|
||||
return FindFieldRecursively(type.BaseType, fieldName);
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to use a UserDataDescriptor that is null to make {fieldName} accessible."));
|
||||
return;
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
var field = IUUD.Type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
if (field == null)
|
||||
{
|
||||
field = FindFieldRecursively(IUUD.Type, fieldName);
|
||||
}
|
||||
|
||||
if (field == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to make field '{fieldName}' accessible, but the field doesn't exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
descriptor.RemoveMember(fieldName);
|
||||
descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
|
||||
}
|
||||
|
||||
private static MethodInfo FindMethodRecursively(Type type, string methodName)
|
||||
{
|
||||
var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
if (method == null && type.BaseType != null)
|
||||
{
|
||||
return FindMethodRecursively(type.BaseType, methodName);
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to use a UserDataDescriptor that is null to make {methodName} accessible."));
|
||||
return;
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
var method = IUUD.Type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
method = FindMethodRecursively(IUUD.Type, methodName);
|
||||
}
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to make method '{methodName}' accessible, but the method doesn't exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
descriptor.RemoveMember(methodName);
|
||||
descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
|
||||
}
|
||||
|
||||
public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to use a UserDataDescriptor that is null to add method {methodName}."));
|
||||
return;
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
descriptor.RemoveMember(methodName);
|
||||
descriptor.AddMember(methodName, new ObjectCallbackMemberDescriptor(methodName, (object arg1, ScriptExecutionContext arg2, CallbackArguments arg3) =>
|
||||
{
|
||||
if (GameMain.LuaCs != null)
|
||||
return GameMain.LuaCs.CallLuaFunction(function, arg3.GetArray());
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
|
||||
public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
GameMain.LuaCs.HandleException(new Exception($"Tried to use a UserDataDescriptor that is null to remove the member {memberName}."));
|
||||
return;
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
descriptor.RemoveMember(memberName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MoonSharp.Interpreter;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
public static class LuaCustomConverters
|
||||
{
|
||||
public static void RegisterAll()
|
||||
{
|
||||
RegisterAction<Item>();
|
||||
RegisterAction<Character>();
|
||||
RegisterAction<Entity>();
|
||||
RegisterAction();
|
||||
|
||||
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<Fixture, Vector2, Vector2, float, float>), v =>
|
||||
{
|
||||
var function = v.Function;
|
||||
return (Func<Fixture, Vector2, Vector2, float, float>)((Fixture a, Vector2 b, Vector2 c, float d) => new LuaResult(function.Call(a, b, c, d)).Float());
|
||||
});
|
||||
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)) ));
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(CsPatch), v => (CsPatch)( (self, args) => new LuaResult(GameMain.LuaCs.CallLuaFunction(v.Function, self, args)) ));
|
||||
|
||||
#if CLIENT
|
||||
RegisterAction<float>();
|
||||
RegisterAction<Microsoft.Xna.Framework.Graphics.SpriteBatch, float>();
|
||||
|
||||
{
|
||||
object Call(object function, params object[] arguments) => GameMain.LuaCs.CallLuaFunction(function, arguments);
|
||||
void RegisterHandler<T>(Func<Closure, object> converter)
|
||||
{
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(T), v => converter(v.Function));
|
||||
}
|
||||
|
||||
RegisterHandler<GUIComponent.SecondaryButtonDownHandler>(f =>
|
||||
(GUIComponent.SecondaryButtonDownHandler)((GUIComponent a1, object a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
|
||||
RegisterHandler<GUIButton.OnClickedHandler>(f =>
|
||||
(GUIButton.OnClickedHandler)((GUIButton a1, object a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
RegisterHandler<GUIButton.OnButtonDownHandler>(f =>
|
||||
(GUIButton.OnButtonDownHandler)(() => new LuaResult(Call(f)).Bool()));
|
||||
RegisterHandler<GUIButton.OnPressedHandler>(f =>
|
||||
(GUIButton.OnPressedHandler)(() => new LuaResult(Call(f)).Bool()));
|
||||
|
||||
RegisterHandler<GUIColorPicker.OnColorSelectedHandler>(f =>
|
||||
(GUIColorPicker.OnColorSelectedHandler)((GUIColorPicker a1, Color a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
|
||||
RegisterHandler<GUIDropDown.OnSelectedHandler>(f =>
|
||||
(GUIDropDown.OnSelectedHandler)((GUIComponent a1, object a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
|
||||
RegisterHandler<GUIListBox.OnSelectedHandler>(f =>
|
||||
(GUIListBox.OnSelectedHandler)((GUIComponent a1, object a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
RegisterHandler<GUIListBox.OnRearrangedHandler>(f =>
|
||||
(GUIListBox.OnRearrangedHandler)((GUIListBox a1, object a2) => Call(f, a1, a2)));
|
||||
RegisterHandler<GUIListBox.CheckSelectedHandler>(f =>
|
||||
(GUIListBox.CheckSelectedHandler)(() => new LuaResult(Call(f)).Object()));
|
||||
|
||||
RegisterHandler<GUINumberInput.OnValueChangedHandler>(f =>
|
||||
(GUINumberInput.OnValueChangedHandler)((GUINumberInput a1) => Call(f, a1)));
|
||||
|
||||
RegisterHandler<GUIProgressBar.ProgressGetterHandler>(f =>
|
||||
(GUIProgressBar.ProgressGetterHandler)(() => new LuaResult(Call(f)).Float()));
|
||||
|
||||
RegisterHandler<GUIRadioButtonGroup.RadioButtonGroupDelegate>(f =>
|
||||
(GUIRadioButtonGroup.RadioButtonGroupDelegate)((GUIRadioButtonGroup a1, int? a2) => Call(f, a1, a2)));
|
||||
|
||||
RegisterHandler<GUIScrollBar.OnMovedHandler>(f =>
|
||||
(GUIScrollBar.OnMovedHandler)((GUIScrollBar a1, float a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
RegisterHandler<GUIScrollBar.ScrollConversion>(f =>
|
||||
(GUIScrollBar.ScrollConversion)((GUIScrollBar a1, float a2) => new LuaResult(Call(f, a1, a2)).Float()));
|
||||
|
||||
RegisterHandler<GUITextBlock.TextGetterHandler>(f =>
|
||||
(GUITextBlock.TextGetterHandler)(() => new LuaResult(Call(f, new object[] { })).String()));
|
||||
|
||||
RegisterHandler<GUITextBox.OnEnterHandler>(f =>
|
||||
(GUITextBox.OnEnterHandler)((GUITextBox a1, string a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
RegisterHandler<GUITextBox.OnTextChangedHandler>(f =>
|
||||
(GUITextBox.OnTextChangedHandler)((GUITextBox a1, string a2) => new LuaResult(Call(f, a1, a2)).Bool()));
|
||||
RegisterHandler<TextBoxEvent>(f =>
|
||||
(TextBoxEvent)((GUITextBox a1, Microsoft.Xna.Framework.Input.Keys a2) => Call(f, a1, a2)));
|
||||
|
||||
RegisterHandler<GUITickBox.OnSelectedHandler>(f =>
|
||||
(GUITickBox.OnSelectedHandler)((GUITickBox a1) => new LuaResult(Call(f, a1)).Bool()));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(Pair<JobPrefab, int>), v =>
|
||||
{
|
||||
return new Pair<JobPrefab, int>((JobPrefab)v.Table.Get(1).ToObject(), (int)v.Table.Get(2).CastToNumber());
|
||||
});
|
||||
|
||||
Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion<UInt64>((Script script, UInt64 v) =>
|
||||
{
|
||||
return DynValue.NewString(v.ToString());
|
||||
});
|
||||
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.UserData, typeof(object), v =>
|
||||
{
|
||||
if (v.UserData.Object is LuaByte lbyte)
|
||||
{
|
||||
return lbyte.Value;
|
||||
}
|
||||
else if (v.UserData.Object is LuaUShort lushort)
|
||||
{
|
||||
return lushort.Value;
|
||||
}
|
||||
else if (v.UserData.Object is LuaFloat lfloat)
|
||||
{
|
||||
return lfloat.Value;
|
||||
}
|
||||
return v.UserData.Object;
|
||||
});
|
||||
}
|
||||
|
||||
public static void RegisterAction<T>()
|
||||
{
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action<T>), v =>
|
||||
{
|
||||
var function = v.Function;
|
||||
return (Action<T>)(p => GameMain.LuaCs.CallLuaFunction(function, p));
|
||||
});
|
||||
}
|
||||
|
||||
public static void RegisterAction<T1, T2>()
|
||||
{
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action<T1, T2>), v =>
|
||||
{
|
||||
var function = v.Function;
|
||||
return (Action<T1, T2>)((a1, a2) => GameMain.LuaCs.CallLuaFunction(function, a1, a2));
|
||||
});
|
||||
}
|
||||
|
||||
public static void RegisterAction()
|
||||
{
|
||||
Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action), v =>
|
||||
{
|
||||
var function = v.Function;
|
||||
return (Action)(() => GameMain.LuaCs.CallLuaFunction(function));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MoonSharp.Interpreter;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Networking;
|
||||
using System.Threading.Tasks;
|
||||
using Barotrauma.Items.Components;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
public static class LuaDocs
|
||||
{
|
||||
|
||||
public static string ConvertTypeName(string type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case "Boolean":
|
||||
return "bool";
|
||||
case "String":
|
||||
return "string";
|
||||
case "int":
|
||||
return "number";
|
||||
case "Single":
|
||||
return "number";
|
||||
case "Double":
|
||||
return "number";
|
||||
case "float":
|
||||
return "number";
|
||||
case "UInt16":
|
||||
return "number";
|
||||
case "UInt32":
|
||||
return "number";
|
||||
case "UInt64":
|
||||
return "number";
|
||||
case "Int32":
|
||||
return "number";
|
||||
case "List`1":
|
||||
return "table";
|
||||
case "Dictionary`2":
|
||||
return "table";
|
||||
}
|
||||
|
||||
if (type.StartsWith("Action"))
|
||||
return "function";
|
||||
|
||||
if (type.StartsWith("Func"))
|
||||
return "function";
|
||||
|
||||
if (type.StartsWith("IEnumerable"))
|
||||
return "Enumerable";
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
public static string EscapeName(string n)
|
||||
{
|
||||
if (n == "end")
|
||||
return "endparam";
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
public static void GenerateDocsAll()
|
||||
{
|
||||
GenerateDocs(typeof(Character), "Character.lua");
|
||||
GenerateDocs(typeof(CharacterInfo), "CharacterInfo.lua");
|
||||
GenerateDocs(typeof(CharacterHealth), "CharacterHealth.lua");
|
||||
GenerateDocs(typeof(AnimController), "AnimController.lua");
|
||||
GenerateDocs(typeof(Client), "Client.lua");
|
||||
GenerateDocs(typeof(Entity), "Entity.lua");
|
||||
GenerateDocs(typeof(EntitySpawner), "Entity.Spawner.lua", "Entity.Spawner");
|
||||
GenerateDocs(typeof(Item), "Item.lua");
|
||||
GenerateDocs(typeof(ItemPrefab), "ItemPrefab.lua");
|
||||
GenerateDocs(typeof(Submarine), "Submarine.lua");
|
||||
GenerateDocs(typeof(SubmarineInfo), "SubmarineInfo.lua");
|
||||
GenerateDocs(typeof(Job), "Job.lua");
|
||||
GenerateDocs(typeof(JobPrefab), "JobPrefab.lua");
|
||||
GenerateDocs(typeof(GameSession), "GameSession.lua", "Game.GameSession");
|
||||
GenerateDocs(typeof(NetLobbyScreen), "NetLobbyScreen.lua", "Game.NetLobbyScreen");
|
||||
GenerateDocs(typeof(GameScreen), "GameScreen.lua", "Game.GameScreen");
|
||||
GenerateDocs(typeof(FarseerPhysics.Dynamics.World), "World.lua", "Game.World");
|
||||
GenerateDocs(typeof(Inventory), "Inventory.lua", "Inventory");
|
||||
GenerateDocs(typeof(ItemInventory), "ItemInventory.lua", "ItemInventory");
|
||||
GenerateDocs(typeof(CharacterInventory), "CharacterInventory.lua", "CharacterInventory");
|
||||
GenerateDocs(typeof(Hull), "Hull.lua", "Hull");
|
||||
GenerateDocs(typeof(Level), "Level.lua", "Level");
|
||||
GenerateDocs(typeof(Affliction), "Affliction.lua", "Affliction");
|
||||
GenerateDocs(typeof(AfflictionPrefab), "AfflictionPrefab.lua", "AfflictionPrefab");
|
||||
GenerateDocs(typeof(WayPoint), "WayPoint.lua", "WayPoint");
|
||||
}
|
||||
|
||||
public static void GenerateDocs(Type type, string name, string categoryName = null)
|
||||
{
|
||||
GenerateDocs(type, "../../../../docs/baseluadocs/" + name, "../../../../docs/lua/generated/" + name, categoryName);
|
||||
}
|
||||
|
||||
public static void GenerateDocs(Type type, string baselua, string fileresult, string categoryName = null)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (categoryName == null)
|
||||
categoryName = type.Name;
|
||||
|
||||
var baseluatext = "";
|
||||
|
||||
if (!File.Exists(baselua))
|
||||
{
|
||||
const string EMPTY_TABLE = "{}";
|
||||
|
||||
baseluatext = @$"-- luacheck: ignore 111
|
||||
|
||||
--[[--
|
||||
{type.FullName}
|
||||
]]
|
||||
-- @code {categoryName}
|
||||
-- @pragma nostrip
|
||||
local {type.Name} = {EMPTY_TABLE}";
|
||||
|
||||
File.WriteAllText(baselua, baseluatext);
|
||||
}
|
||||
else
|
||||
baseluatext = File.ReadAllText(baselua);
|
||||
|
||||
HashSet<string> removed = new HashSet<string>();
|
||||
|
||||
foreach(var line in baseluatext.Split('\n'))
|
||||
{
|
||||
if(line.Contains("-- @remove "))
|
||||
{
|
||||
var replaced = line.Replace("-- @remove ", "").Replace("\r", "");
|
||||
removed.Add(replaced);
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(baseluatext + "\n\n");
|
||||
|
||||
var members = type.GetMembers();
|
||||
|
||||
foreach(var member in members)
|
||||
{
|
||||
Console.WriteLine("'{0}' is a {1}", member.Name, member.MemberType);
|
||||
|
||||
if (member.MemberType == MemberTypes.Method)
|
||||
{
|
||||
var method = (MethodInfo)member;
|
||||
|
||||
if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))
|
||||
continue;
|
||||
|
||||
var lsb = new StringBuilder();
|
||||
|
||||
lsb.Append($"--- {method.Name}\n");
|
||||
lsb.Append($"-- @realm shared\n");
|
||||
|
||||
var paramNames = "";
|
||||
|
||||
var parameters = method.GetParameters();
|
||||
for(var i=0; i < parameters.Length; i++)
|
||||
{
|
||||
var parameter = parameters[i];
|
||||
|
||||
if(i == parameters.Length - 1)
|
||||
paramNames = paramNames + EscapeName(parameter.Name);
|
||||
else
|
||||
paramNames = paramNames + EscapeName(parameter.Name) + ", ";
|
||||
|
||||
lsb.Append($"-- @tparam {ConvertTypeName(parameter.ParameterType.Name)} {EscapeName(parameter.Name)}\n");
|
||||
}
|
||||
|
||||
if (method.ReturnType != typeof(void))
|
||||
{
|
||||
lsb.Append($"-- @treturn {ConvertTypeName(method.ReturnType.Name)}\n");
|
||||
}
|
||||
|
||||
string functionDecoration;
|
||||
|
||||
if (method.IsStatic)
|
||||
functionDecoration = $"function {type.Name}.{method.Name}({paramNames}) end";
|
||||
else
|
||||
functionDecoration = $"function {method.Name}({paramNames}) end";
|
||||
|
||||
if (removed.Contains(functionDecoration))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lsb.Append(functionDecoration);
|
||||
|
||||
lsb.Append("\n\n");
|
||||
sb.Append(lsb);
|
||||
}
|
||||
|
||||
if (member.MemberType == MemberTypes.Field)
|
||||
{
|
||||
var lsb = new StringBuilder();
|
||||
|
||||
var field = (FieldInfo)member;
|
||||
|
||||
lsb.Append($"---\n");
|
||||
lsb.Append($"-- ");
|
||||
|
||||
var name = EscapeName(field.Name);
|
||||
|
||||
var returnName = ConvertTypeName(field.FieldType.Name);
|
||||
|
||||
if (field.IsStatic)
|
||||
name = type.Name + "." + field.Name;
|
||||
|
||||
if (removed.Contains(name))
|
||||
continue;
|
||||
|
||||
lsb.Append(name);
|
||||
lsb.Append($", Field of type {returnName}\n");
|
||||
lsb.Append($"-- @realm shared\n");
|
||||
lsb.Append($"-- @{returnName} {name}\n");
|
||||
|
||||
lsb.Append("\n");
|
||||
sb.Append(lsb);
|
||||
}
|
||||
|
||||
if (member.MemberType == MemberTypes.Property)
|
||||
{
|
||||
var lsb = new StringBuilder();
|
||||
|
||||
var property = (PropertyInfo)member;
|
||||
|
||||
lsb.Append($"---\n");
|
||||
lsb.Append($"-- ");
|
||||
|
||||
var name = EscapeName(property.Name);
|
||||
|
||||
var returnName = ConvertTypeName(property.PropertyType.Name);
|
||||
|
||||
if (property.GetGetMethod().IsStatic)
|
||||
name = type.Name + "." + property.Name;
|
||||
|
||||
if (removed.Contains(name))
|
||||
continue;
|
||||
|
||||
lsb.Append(name);
|
||||
lsb.Append($", Field of type {returnName}\n");
|
||||
lsb.Append($"-- @realm shared\n");
|
||||
lsb.Append($"-- @{returnName} {name}\n");
|
||||
|
||||
lsb.Append("\n");
|
||||
sb.Append(lsb);
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(fileresult, sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using MoonSharp.Interpreter;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Loaders;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class LuaScriptLoader : ScriptLoaderBase
|
||||
{
|
||||
|
||||
public override object LoadFile(string file, Table globalContext)
|
||||
{
|
||||
if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return null;
|
||||
|
||||
return File.ReadAllText(file);
|
||||
}
|
||||
|
||||
public override bool ScriptFileExists(string file)
|
||||
{
|
||||
if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return false;
|
||||
|
||||
return File.Exists(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private Harmony harmony;
|
||||
|
||||
private Dictionary<string, Dictionary<string, (LuaCsHookCallback, ACsMod)>> hookFunctions;
|
||||
|
||||
private Dictionary<long, HashSet<(string, CsPatch, ACsMod)>> hookPrefixMethods;
|
||||
@@ -54,7 +56,11 @@ namespace Barotrauma
|
||||
|
||||
private Queue<(float, CsAction, object[])> queuedFunctionCalls;
|
||||
|
||||
private LuaCsHook() {
|
||||
private static LuaCsHook instance;
|
||||
|
||||
public LuaCsHook() {
|
||||
instance = this;
|
||||
|
||||
hookFunctions = new Dictionary<string, Dictionary<string, (LuaCsHookCallback, ACsMod)>>();
|
||||
|
||||
hookPrefixMethods = new Dictionary<long, HashSet<(string, CsPatch, ACsMod)>>();
|
||||
@@ -63,10 +69,12 @@ namespace Barotrauma
|
||||
queuedFunctionCalls = new Queue<(float, CsAction, object[])>();
|
||||
}
|
||||
|
||||
private static LuaCsHook _inst;
|
||||
static LuaCsHook() => _inst = new LuaCsHook();
|
||||
public static LuaCsHook Instance { get => _inst; }
|
||||
public void Initialize()
|
||||
{
|
||||
harmony = new Harmony("LuaCsForBarotrauma");
|
||||
|
||||
}
|
||||
|
||||
private static void _hookLuaCsPatch(MethodBase __originalMethod, object[] __args, object __instance, out object result, HookMethodType hookMethodType)
|
||||
{
|
||||
result = null;
|
||||
@@ -81,10 +89,10 @@ namespace Barotrauma
|
||||
switch (hookMethodType)
|
||||
{
|
||||
case HookMethodType.Before:
|
||||
_inst.hookPrefixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
instance.hookPrefixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
break;
|
||||
case HookMethodType.After:
|
||||
_inst.hookPostfixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
instance.hookPostfixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -196,7 +204,6 @@ namespace Barotrauma
|
||||
|
||||
public void HookMethod(string identifier, MethodInfo method, CsPatch patch, HookMethodType hookType = HookMethodType.Before, ACsMod owner = null)
|
||||
{
|
||||
Console.WriteLine($" --== '{identifier}' {method.ReflectedType.Name}.{method.Name} -> {method.ReturnType.Name} | {hookType.ToString("G")}");
|
||||
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());
|
||||
@@ -208,14 +215,14 @@ namespace Barotrauma
|
||||
{
|
||||
if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPrefix) == null)
|
||||
{
|
||||
GameMain.LuaCs.harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchRetPrefix));
|
||||
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));
|
||||
harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchPrefix));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,14 +243,14 @@ namespace Barotrauma
|
||||
{
|
||||
if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPostfix) == null)
|
||||
{
|
||||
GameMain.LuaCs.harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchRetPostfix));
|
||||
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));
|
||||
harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchPostfix));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +319,6 @@ namespace Barotrauma
|
||||
{
|
||||
name = name.ToLower();
|
||||
|
||||
LuaCsSetup.PrintLogMessage($"'{name}' | '{hookName}'");
|
||||
if (name == null || hookName == null || hook == null) throw new ArgumentNullException("Names and Hook must not be null");
|
||||
|
||||
if (!hookFunctions.ContainsKey(name))
|
||||
@@ -340,7 +346,7 @@ namespace Barotrauma
|
||||
|
||||
queuedFunctionCalls.Clear();
|
||||
|
||||
GameMain.LuaCs.harmony?.UnpatchAll();
|
||||
harmony?.UnpatchAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,19 +24,18 @@ namespace Barotrauma
|
||||
|
||||
internal LuaCsHook Hook { get; private set; }
|
||||
|
||||
public LuaGame game;
|
||||
public LuaCsNetworking networking;
|
||||
public Harmony harmony;
|
||||
public LuaGame Game;
|
||||
public LuaCsNetworking Networking;
|
||||
|
||||
public LuaScriptLoader luaScriptLoader;
|
||||
public CsScriptLoader netScriptLoader;
|
||||
public LuaScriptLoader LuaScriptLoader;
|
||||
public CsScriptLoader NetScriptLoader;
|
||||
|
||||
public LuaCsSetup()
|
||||
{
|
||||
Hook = LuaCsHook.Instance;
|
||||
Hook = new LuaCsHook();
|
||||
|
||||
game = new LuaGame();
|
||||
networking = new LuaCsNetworking();
|
||||
Game = new LuaGame();
|
||||
Networking = new LuaCsNetworking();
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +264,7 @@ namespace Barotrauma
|
||||
|
||||
public void SetModulePaths(string[] str)
|
||||
{
|
||||
luaScriptLoader.ModulePaths = str;
|
||||
LuaScriptLoader.ModulePaths = str;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
@@ -279,31 +278,12 @@ namespace Barotrauma
|
||||
ACsMod.LoadedMods.Clear();
|
||||
Hook?.Call("stop");
|
||||
|
||||
game?.Stop();
|
||||
//harmony?.UnpatchAll();
|
||||
Game?.Stop();
|
||||
|
||||
//Hook = new LuaCsHook();
|
||||
Hook.Clear();
|
||||
game = new LuaGame();
|
||||
networking = new LuaCsNetworking();
|
||||
luaScriptLoader = null;
|
||||
}
|
||||
|
||||
private void InitCs()
|
||||
{
|
||||
netScriptLoader = new CsScriptLoader(this);
|
||||
netScriptLoader.SearchFolders();
|
||||
if (netScriptLoader == null) throw new Exception("LuaCsSetup was not properly initialized.");
|
||||
try
|
||||
{
|
||||
var modTypes = netScriptLoader.Compile();
|
||||
//modTypes.ForEach(t => ACsMod.CreateInstance(t));
|
||||
modTypes.ForEach(t => t.GetConstructor(new Type[] { })?.Invoke(null));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PrintMessage(ex);
|
||||
}
|
||||
Game = new LuaGame();
|
||||
Networking = new LuaCsNetworking();
|
||||
LuaScriptLoader = null;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
@@ -312,32 +292,27 @@ namespace Barotrauma
|
||||
|
||||
PrintMessage("LuaCs! Version " + AssemblyInfo.GitRevision);
|
||||
|
||||
luaScriptLoader = new LuaScriptLoader();
|
||||
luaScriptLoader.ModulePaths = new string[] { };
|
||||
InitCs();
|
||||
LuaScriptLoader = new LuaScriptLoader();
|
||||
LuaScriptLoader.ModulePaths = new string[] { };
|
||||
|
||||
NetScriptLoader = new CsScriptLoader(this);
|
||||
|
||||
LuaCustomConverters.RegisterAll();
|
||||
|
||||
lua = new Script(CoreModules.Preset_SoftSandbox | CoreModules.Debug);
|
||||
lua.Options.DebugPrint = PrintMessage;
|
||||
lua.Options.ScriptLoader = luaScriptLoader;
|
||||
lua.Options.ScriptLoader = LuaScriptLoader;
|
||||
|
||||
harmony = new Harmony("com.LuaForBarotrauma");
|
||||
harmony.UnpatchAll();
|
||||
Hook.Initialize();
|
||||
Game = new LuaGame();
|
||||
Networking = new LuaCsNetworking();
|
||||
|
||||
//Hook = new LuaCsHook();
|
||||
game = new LuaGame();
|
||||
networking = new LuaCsNetworking();
|
||||
|
||||
//UserData.RegisterType<LuaCsHook>();
|
||||
UserData.RegisterType<LuaGame>();
|
||||
UserData.RegisterType<LuaCsTimer>();
|
||||
UserData.RegisterType<LuaCsFile>();
|
||||
UserData.RegisterType<LuaCsNetworking>();
|
||||
UserData.RegisterType<LuaUserData>();
|
||||
UserData.RegisterType<IUserDataDescriptor>();
|
||||
|
||||
lua.Globals["printerror"] = (Action<object>)PrintError;
|
||||
|
||||
var hookType = UserData.RegisterType<LuaCsHook>();
|
||||
var hookDesc = (StandardUserDataDescriptor)hookType;
|
||||
@@ -353,6 +328,8 @@ namespace Barotrauma
|
||||
}
|
||||
});
|
||||
|
||||
lua.Globals["printerror"] = (Action<object>)PrintError;
|
||||
|
||||
lua.Globals["setmodulepaths"] = (Action<string[]>)SetModulePaths;
|
||||
|
||||
lua.Globals["dofile"] = (Func<string, Table, string, DynValue>)DoFile;
|
||||
@@ -363,11 +340,11 @@ namespace Barotrauma
|
||||
lua.Globals["load"] = (Func<string, Table, string, DynValue>)LoadString;
|
||||
|
||||
lua.Globals["LuaUserData"] = UserData.CreateStatic<LuaUserData>();
|
||||
lua.Globals["Game"] = game;
|
||||
lua.Globals["Game"] = Game;
|
||||
lua.Globals["Hook"] = Hook;
|
||||
lua.Globals["Timer"] = new LuaCsTimer();
|
||||
lua.Globals["File"] = UserData.CreateStatic<LuaCsFile>();
|
||||
lua.Globals["Networking"] = networking;
|
||||
lua.Globals["Networking"] = Networking;
|
||||
|
||||
bool isServer;
|
||||
|
||||
@@ -382,6 +359,20 @@ namespace Barotrauma
|
||||
|
||||
// LuaDocs.GenerateDocsAll();
|
||||
|
||||
|
||||
NetScriptLoader.SearchFolders();
|
||||
if (NetScriptLoader == null) throw new Exception("LuaCsSetup was not properly initialized.");
|
||||
try
|
||||
{
|
||||
var modTypes = NetScriptLoader.Compile();
|
||||
modTypes.ForEach(t => t.GetConstructor(new Type[] { })?.Invoke(null));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PrintMessage(ex);
|
||||
}
|
||||
|
||||
|
||||
ContentPackage luaPackage = GetPackage();
|
||||
|
||||
if (File.Exists(LUASETUP_FILE))
|
||||
@@ -411,7 +402,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintError("LuaCs loader not found! Lua/LuaSetup.lua, no Lua scripts will be executed or work.");
|
||||
PrintError("LuaSetup.lua not found! Lua/LuaSetup.lua, no Lua scripts will be executed or work.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user