separated Lua source by client, server and shared

github desktop bugged
This commit is contained in:
Evil Factory
2021-09-15 12:59:19 -03:00
parent 5678f81326
commit 4075e71f7a
12 changed files with 750 additions and 612 deletions

View File

@@ -3096,6 +3096,22 @@ namespace Barotrauma
NewMessage("Level seed: " + Level.Loaded.Seed);
}
});
commands.Add(new Command("lua_cl", "lua_cl: runs a string on the client", (string[] args) =>
{
if (GameMain.Client != null)
GameMain.Lua.DoString(string.Join(" ", args));
else
ThrowError("Client not connected to any server.");
}));
commands.Add(new Command("reloadlua_cl", "reloads lua on the client", (string[] args) =>
{
if (GameMain.Client != null)
GameMain.Lua.Initialize();
else
ThrowError("Client not connected to any server.");
}));
}
private static void ReloadWearables(Character character, int variant = 0)

View File

@@ -23,6 +23,8 @@ namespace Barotrauma
{
class GameMain : Game
{
public static LuaSetup Lua;
public static bool ShowFPS = false;
public static bool ShowPerf = false;
public static bool DebugDraw;
@@ -210,6 +212,8 @@ namespace Barotrauma
Config = new GameSettings();
Lua = new LuaSetup();
Md5Hash.LoadCache();
ConsoleArguments = args;

View File

@@ -393,6 +393,8 @@ namespace Barotrauma.Networking
{
GameMain.NetLobbyScreen.ChatInput.Enabled = true;
}
GameMain.Lua.Initialize();
};
clientPeer.OnRequestPassword = (int salt, int retries) =>
{
@@ -2690,6 +2692,8 @@ namespace Barotrauma.Networking
public override void Disconnect()
{
GameMain.Lua.Stop();
allowReconnect = false;
if (clientPeer is SteamP2PClientPeer || clientPeer is SteamP2POwnerPeer)

View File

@@ -1,21 +1,11 @@
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
{
return GameMain.Server.ConnectedClients;
}
}
public void SetClientCharacter(Character character)
{
GameMain.Server.SetClientCharacter(this, character);
@@ -48,88 +38,30 @@ namespace Barotrauma.Networking
return this.Permissions.HasFlag(permissions);
}
}
}
namespace Barotrauma
namespace Barotrauma
{
using Barotrauma.Networking;
using System.Linq;
using System.Reflection;
partial class Character
{
}
partial class AfflictionPrefab
{
public static AfflictionPrefab[] ListArray
{
get
{
return List.ToArray();
}
}
}
partial class CharacterInfo
{
public static CharacterInfo Create(string speciesName, string name = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, string npcIdentifier = "")
{
return new CharacterInfo(speciesName, name, name, jobPrefab, ragdollFileName, variant, randSync, npcIdentifier);
}
}
partial class Item
{
public static void AddToRemoveQueue(Item item)
{
EntitySpawner.Spawner.AddToRemoveQueue(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);
}
}
using Microsoft.Xna.Framework;
partial class ItemPrefab
{
public static void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, object spawned = null)
{
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, position, onSpawned: (Item item) => {
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, position, onSpawned: (Item item) =>
{
GameMain.Lua.CallFunction(spawned, new object[] { item });
});
}
public static void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, object spawned = null)
{
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, inventory, onSpawned: (Item item) => {
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, inventory, onSpawned: (Item item) =>
{
GameMain.Lua.CallFunction(spawned, new object[] { item });
});
}
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;
}
}
}
namespace Barotrauma.Items.Components
@@ -159,4 +91,6 @@ namespace Barotrauma.Items.Components
return new Signal(value, stepsTaken, sender, source, power, strength);
}
}
}

View File

@@ -11,27 +11,71 @@ using System.Net;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
partial class LuaSetup
{
private static Vector2 CreateVector2(float x, float y)
partial class LuaGame
{
return new Vector2(x, y);
public bool IsDedicated
{
get
{
return GameMain.Server.ServerPeer is LidgrenServerPeer;
}
}
public ServerSettings ServerSettings => GameMain.Server.ServerSettings;
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, string 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();
}
}
private static Vector3 CreateVector3(float x, float y, float z)
{
return new Vector3(x, y, z);
}
private static Vector4 CreateVector4(float x, float y, float z, float w)
{
return new Vector4(x, y, z, w);
}
private class LuaPlayer
partial class LuaPlayer
{
public static List<Character> GetAllCharacters()
@@ -89,22 +133,22 @@ namespace Barotrauma
public static void SetSpectatorPos(Client client, Vector2 pos)
{
}
public static void SetRadioRange(Character character, float range)
{
if(character.Inventory == null) { return; }
if (character.Inventory == null) { return; }
foreach(Item item in character.Inventory.AllItems)
foreach (Item item in character.Inventory.AllItems)
{
if(item == null) { continue; }
if (item == null) { continue; }
if(item.Name == "Headset")
if (item.Name == "Headset")
{
item.GetComponent<Items.Components.WifiComponent>().Range = range;
}
}
}
}
public static bool CheckPermission(Client client, ClientPermissions permissions)
@@ -112,521 +156,5 @@ namespace Barotrauma
return client.Permissions.HasFlag(permissions);
}
}
public class LuaGame
{
LuaSetup env;
public LuaGame(LuaSetup e)
{
env = e;
}
public bool allowWifiChat = false;
public bool overrideTraitors = false;
public bool overrideRespawnSub = false;
public bool overrideSignalRadio = false;
public bool disableSpamFilter = false;
public bool RoundStarted
{
get
{
return GameMain.Server.GameStarted;
}
}
public bool IsDedicated
{
get
{
return GameMain.Server.ServerPeer is LidgrenServerPeer;
}
}
public ServerSettings Settings => GameMain.Server.ServerSettings;
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, string 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 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 static void Log(string message, ServerLog.MessageType type)
{
GameServer.Log(message, type);
}
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 Character Spawn(string name, Vector2 worldPos)
{
Character spawnedCharacter = null;
Vector2 spawnPosition = worldPos;
string characterLowerCase = name.ToLowerInvariant();
JobPrefab job = null;
if (!JobPrefab.Prefabs.ContainsKey(characterLowerCase))
{
job = JobPrefab.Prefabs.Find(jp => jp.Name != null && jp.Name.Equals(characterLowerCase, StringComparison.OrdinalIgnoreCase));
}
else
{
job = JobPrefab.Prefabs[characterLowerCase];
}
bool human = job != null || characterLowerCase == CharacterPrefab.HumanSpeciesName;
if (string.IsNullOrWhiteSpace(name)) { return null; }
if (human)
{
var variant = job != null ? Rand.Range(0, job.Variants, Rand.RandSync.Server) : 0;
CharacterInfo characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: job, variant: variant);
spawnedCharacter = Character.Create(characterInfo, spawnPosition, ToolBox.RandomSeed(8));
if (GameMain.GameSession != null)
{
//TODO: a way to select which team to spawn to?
spawnedCharacter.TeamID = Character.Controlled != null ? Character.Controlled.TeamID : CharacterTeamType.Team1;
#if CLIENT
GameMain.GameSession.CrewManager.AddCharacter(spawnedCharacter);
#endif
}
spawnedCharacter.GiveJobItems(null);
spawnedCharacter.Info.StartItemsGiven = true;
}
else
{
if (CharacterPrefab.FindBySpeciesName(name) != null)
{
spawnedCharacter = Character.Create(name, spawnPosition, ToolBox.RandomSeed(8));
}
}
return spawnedCharacter;
}
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 void RemoveItem(Item item)
{
EntitySpawner.Spawner.AddToRemoveQueue(item);
}
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 void AddItemPrefabToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, DynValue spawned = null)
{
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, position, onSpawned: (Item item) => {
if (spawned?.Type == DataType.Function) env.lua.Call(spawned, UserData.Create(item));
});
}
public void AddItemPrefabToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, DynValue spawned = null)
{
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, inventory, onSpawned: (Item item) => {
if (spawned?.Type == DataType.Function) env.lua.Call(spawned, UserData.Create(item));
});
}
public static Submarine GetRespawnSub()
{
if (GameMain.Server.RespawnManager == null)
return null;
return GameMain.Server.RespawnManager.RespawnShuttle;
}
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 DispatchRespawnSub()
{
GameMain.Server.RespawnManager.DispatchShuttle();
}
public static void SetRespawnSubTeam(int team)
{
GameMain.Server.RespawnManager.RespawnShuttle.TeamID = (CharacterTeamType)team;
}
public static void ExecuteCommand(string command)
{
DebugConsole.ExecuteCommand(command);
}
public static void StartGame()
{
GameMain.Server.StartGame();
}
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);
}
public static ContentPackage[] GetEnabledContentPackages()
{
return GameMain.Config.AllEnabledPackages.ToArray();
}
public static List<string> GetEnabledPackagesDirectlyFromFile()
{
List<string> enabledPackages = new List<string>();
XDocument doc = XMLExtensions.LoadXml("config_player.xml");
var contentPackagesElement = doc.Root.Element("contentpackages");
string coreName = contentPackagesElement.Element("core")?.GetAttributeString("name", "");
enabledPackages.Add(coreName);
XElement regularElement = contentPackagesElement.Element("regular");
List<XElement> subElements = regularElement?.Elements()?.ToList();
foreach (var subElement in subElements)
{
if (!bool.TryParse(subElement.GetAttributeString("enabled", "false"), out bool enabled) || !enabled) { continue; }
string name = subElement.GetAttributeString("name", null);
enabledPackages.Add(name);
}
return enabledPackages;
}
}
private class LuaTimer
{
public LuaSetup env;
public LuaTimer(LuaSetup e)
{
env = e;
}
public static double GetTime()
{
return Timing.TotalTime;
}
}
private class LuaRandom
{
Random random;
public LuaRandom()
{
random = new Random();
}
public int Range(int min, int max)
{
return random.Next(min, max);
}
public float RangeFloat(float min, float max)
{
double range = (double)max - (double)min;
double sample = random.NextDouble();
double scaled = (sample * range) + min;
float f = (float)scaled;
return f;
}
}
private class LuaFile
{
// TODO: SANDBOXING
public static string Read(string path)
{
return File.ReadAllText(path);
}
public static void Write(string path, string text)
{
File.WriteAllText(path, text);
}
public static bool Exists(string path)
{
return File.Exists(path);
}
public static bool DirectoryExists(string path)
{
return Directory.Exists(path);
}
public static string[] GetFiles(string path)
{
return Directory.GetFiles(path);
}
public static string[] GetDirectories(string path)
{
return Directory.GetDirectories(path);
}
public 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))
{
foreach (string f in Directory.GetFiles(d))
{
files.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
return files.ToArray();
}
}
private class LuaNetworking
{
public LuaSetup env;
public LuaNetworking(LuaSetup e)
{
env = e;
}
public string RequestPostHTTP(string url, string data, string contentType = "application/json")
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = contentType;
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
streamWriter.Write(data);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
return streamReader.ReadToEnd();
}catch(Exception e)
{
return e.ToString();
}
}
public string RequestGetHTTP(string url)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
return streamReader.ReadToEnd();
}catch(Exception e)
{
return e.ToString();
}
}
}
public class LuaHook
{
public LuaSetup env;
public LuaHook(LuaSetup e)
{
env = e;
}
public class HookFunction
{
public string name;
public string hookName;
public object function;
public HookFunction(string n, string hn, object func)
{
name = n;
hookName = hn;
function = func;
}
}
public Dictionary<string, Dictionary<string, HookFunction>> hookFunctions = new Dictionary<string, Dictionary<string, HookFunction>>();
public void Add(string name, string hookName, object function)
{
if (name == null && hookName == null && function == null) return;
if (!hookFunctions.ContainsKey(name))
hookFunctions.Add(name, new Dictionary<string, HookFunction>());
hookFunctions[name][hookName] = new HookFunction(name, hookName, function);
}
public void Remove(string name, string hookName)
{
if (name == null && hookName == null) return;
if (!hookFunctions.ContainsKey(name))
return;
if(hookFunctions[name].ContainsKey(hookName))
hookFunctions[name].Remove(hookName);
}
public object Call(string name, object[] args)
{
if (name == null) return null;
if (!hookFunctions.ContainsKey(name))
return null;
object lastResult = null;
foreach (HookFunction hf in hookFunctions[name].Values)
{
try
{
if (hf.function is Closure)
lastResult = env.lua.Call(hf.function, args);
// else if (hf.function is NLua.LuaFunction luaFunction)
// lastResult = luaFunction.Call(args);
}
catch (Exception e)
{
env.HandleLuaException(e);
}
}
return lastResult;
}
}
}
}
}

View File

@@ -0,0 +1,106 @@
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 AfflictionPrefab
{
public static AfflictionPrefab[] ListArray
{
get
{
return List.ToArray();
}
}
}
partial class CharacterInfo
{
public static CharacterInfo Create(string speciesName, string name = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, string npcIdentifier = "")
{
return new CharacterInfo(speciesName, name, name, jobPrefab, ragdollFileName, variant, randSync, npcIdentifier);
}
}
partial class Item
{
public static void AddToRemoveQueue(Item item)
{
EntitySpawner.Spawner.AddToRemoveQueue(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;
}
}
}
namespace Barotrauma.Items.Components
{
using Barotrauma.Networking;
partial class CustomInterface
{
}
partial struct Signal
{
}
}

View File

@@ -0,0 +1,507 @@
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;
namespace Barotrauma
{
partial class LuaSetup
{
private static Vector2 CreateVector2(float x, float y)
{
return new Vector2(x, y);
}
private static Vector3 CreateVector3(float x, float y, float z)
{
return new Vector3(x, y, z);
}
private static Vector4 CreateVector4(float x, float y, float z, float w)
{
return new Vector4(x, y, z, w);
}
private partial class LuaPlayer
{
}
public partial class LuaGame
{
LuaSetup env;
public LuaGame(LuaSetup e)
{
env = e;
}
public bool allowWifiChat = false;
public bool overrideTraitors = false;
public bool overrideRespawnSub = false;
public bool overrideSignalRadio = false;
public bool disableSpamFilter = false;
public bool RoundStarted
{
get
{
#if SERVER
return GameMain.Server.GameStarted;
#else
return GameMain.Client.GameStarted;
#endif
}
}
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 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 Character Spawn(string name, Vector2 worldPos)
{
Character spawnedCharacter = null;
Vector2 spawnPosition = worldPos;
string characterLowerCase = name.ToLowerInvariant();
JobPrefab job = null;
if (!JobPrefab.Prefabs.ContainsKey(characterLowerCase))
{
job = JobPrefab.Prefabs.Find(jp => jp.Name != null && jp.Name.Equals(characterLowerCase, StringComparison.OrdinalIgnoreCase));
}
else
{
job = JobPrefab.Prefabs[characterLowerCase];
}
bool human = job != null || characterLowerCase == CharacterPrefab.HumanSpeciesName;
if (string.IsNullOrWhiteSpace(name)) { return null; }
if (human)
{
var variant = job != null ? Rand.Range(0, job.Variants, Rand.RandSync.Server) : 0;
CharacterInfo characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: job, variant: variant);
spawnedCharacter = Character.Create(characterInfo, spawnPosition, ToolBox.RandomSeed(8));
if (GameMain.GameSession != null)
{
//TODO: a way to select which team to spawn to?
spawnedCharacter.TeamID = Character.Controlled != null ? Character.Controlled.TeamID : CharacterTeamType.Team1;
#if CLIENT
GameMain.GameSession.CrewManager.AddCharacter(spawnedCharacter);
#endif
}
spawnedCharacter.GiveJobItems(null);
spawnedCharacter.Info.StartItemsGiven = true;
}
else
{
if (CharacterPrefab.FindBySpeciesName(name) != null)
{
spawnedCharacter = Character.Create(name, spawnPosition, ToolBox.RandomSeed(8));
}
}
return spawnedCharacter;
}
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 void RemoveItem(Item item)
{
EntitySpawner.Spawner.AddToRemoveQueue(item);
}
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 void AddItemPrefabToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, DynValue spawned = null)
{
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, position, onSpawned: (Item item) => {
if (spawned?.Type == DataType.Function) env.lua.Call(spawned, UserData.Create(item));
});
}
public void AddItemPrefabToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, DynValue spawned = null)
{
EntitySpawner.Spawner.AddToSpawnQueue(itemPrefab, inventory, onSpawned: (Item item) => {
if (spawned?.Type == DataType.Function) env.lua.Call(spawned, UserData.Create(item));
});
}
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);
}
public static ContentPackage[] GetEnabledContentPackages()
{
return GameMain.Config.AllEnabledPackages.ToArray();
}
public static List<string> GetEnabledPackagesDirectlyFromFile()
{
List<string> enabledPackages = new List<string>();
XDocument doc = XMLExtensions.LoadXml("config_player.xml");
var contentPackagesElement = doc.Root.Element("contentpackages");
string coreName = contentPackagesElement.Element("core")?.GetAttributeString("name", "");
enabledPackages.Add(coreName);
XElement regularElement = contentPackagesElement.Element("regular");
List<XElement> subElements = regularElement?.Elements()?.ToList();
foreach (var subElement in subElements)
{
if (!bool.TryParse(subElement.GetAttributeString("enabled", "false"), out bool enabled) || !enabled) { continue; }
string name = subElement.GetAttributeString("name", null);
enabledPackages.Add(name);
}
return enabledPackages;
}
}
private partial class LuaTimer
{
public LuaSetup env;
public LuaTimer(LuaSetup e)
{
env = e;
}
public static double GetTime()
{
return Timing.TotalTime;
}
}
private partial class LuaRandom
{
Random random;
public LuaRandom()
{
random = new Random();
}
public int Range(int min, int max)
{
return random.Next(min, max);
}
public float RangeFloat(float min, float max)
{
double range = (double)max - (double)min;
double sample = random.NextDouble();
double scaled = (sample * range) + min;
float f = (float)scaled;
return f;
}
}
private partial class LuaFile
{
// TODO: SANDBOXING
public static string Read(string path)
{
return File.ReadAllText(path);
}
public static void Write(string path, string text)
{
File.WriteAllText(path, text);
}
public static bool Exists(string path)
{
return File.Exists(path);
}
public static bool DirectoryExists(string path)
{
return Directory.Exists(path);
}
public static string[] GetFiles(string path)
{
return Directory.GetFiles(path);
}
public static string[] GetDirectories(string path)
{
return Directory.GetDirectories(path);
}
public 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))
{
foreach (string f in Directory.GetFiles(d))
{
files.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
return files.ToArray();
}
}
private partial class LuaNetworking
{
public LuaSetup env;
public LuaNetworking(LuaSetup e)
{
env = e;
}
public string RequestPostHTTP(string url, string data, string contentType = "application/json")
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = contentType;
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
streamWriter.Write(data);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
return streamReader.ReadToEnd();
}catch(Exception e)
{
return e.ToString();
}
}
public string RequestGetHTTP(string url)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
return streamReader.ReadToEnd();
}catch(Exception e)
{
return e.ToString();
}
}
}
public partial class LuaHook
{
public LuaSetup env;
public LuaHook(LuaSetup e)
{
env = e;
}
public class HookFunction
{
public string name;
public string hookName;
public object function;
public HookFunction(string n, string hn, object func)
{
name = n;
hookName = hn;
function = func;
}
}
public Dictionary<string, Dictionary<string, HookFunction>> hookFunctions = new Dictionary<string, Dictionary<string, HookFunction>>();
public void Add(string name, string hookName, object function)
{
if (name == null && hookName == null && function == null) return;
if (!hookFunctions.ContainsKey(name))
hookFunctions.Add(name, new Dictionary<string, HookFunction>());
hookFunctions[name][hookName] = new HookFunction(name, hookName, function);
}
public void Remove(string name, string hookName)
{
if (name == null && hookName == null) return;
if (!hookFunctions.ContainsKey(name))
return;
if(hookFunctions[name].ContainsKey(hookName))
hookFunctions[name].Remove(hookName);
}
public object Call(string name, object[] args)
{
if (name == null) return null;
if(args == null) { args = new object[] { }; }
if (!hookFunctions.ContainsKey(name))
return null;
object lastResult = null;
foreach (HookFunction hf in hookFunctions[name].Values)
{
try
{
if (hf.function is Closure)
lastResult = env.lua.Call(hf.function, args);
// else if (hf.function is NLua.LuaFunction luaFunction)
// lastResult = luaFunction.Call(args);
}
catch (Exception e)
{
env.HandleLuaException(e);
}
}
return lastResult;
}
}
}
}

View File

@@ -41,6 +41,8 @@ namespace Barotrauma
{
if (message == null) { message = "nil"; }
Console.WriteLine(message.ToString());
#if SERVER
if (GameMain.Server != null)
{
foreach (var c in GameMain.Server.ConnectedClients)
@@ -50,6 +52,10 @@ namespace Barotrauma
GameServer.Log("[LUA] " + message.ToString(), ServerLog.MessageType.ServerMessage);
}
#else
DebugConsole.NewMessage("[LUA] " + message.ToString());
#endif
}
public void PrintMessageNoLog(object message)
@@ -158,6 +164,17 @@ namespace Barotrauma
return value * 2;
}
public void Stop()
{
lua = null;
hook = null;
game = null;
luaScriptLoader = null;
luaSetup = null;
}
public void Initialize()
{
luaSetup = this;
@@ -246,6 +263,8 @@ namespace Barotrauma
UserData.RegisterType<AITarget>();
UserData.RegisterType<AITargetMemory>();
UserData.RegisterType<ServerSettings>();
UserData.RegisterType<PrefabCollection<ItemPrefab>>();
UserData.RegisterType<PrefabCollection<JobPrefab>>();
lua = new Script(CoreModules.Preset_SoftSandbox);
@@ -307,6 +326,21 @@ namespace Barotrauma
lua.Globals["ClientPermissions"] = UserData.CreateStatic<ClientPermissions>();
lua.Globals["Signal"] = UserData.CreateStatic<Signal>();
bool isServer = true;
#if SERVER
isServer = true;
#else
isServer = false;
#endif
lua.Globals["SERVER"] = isServer;
lua.Globals["CLIENT"] = !isServer;
#if CLIENT
return;
#endif
if (File.Exists("Lua/MoonsharpSetup.lua")) // try the default loader
DoFile("Lua/MoonsharpSetup.lua");
else if (File.Exists("Mods/LuaForBarotrauma/Lua/MoonsharpSetup.lua")) // in case its the workshop version

View File

@@ -34,4 +34,9 @@ function Client.Unban(player, endpoint) end
--- List of all connected clients.
-- @treturn table
-- @realm shared
Client.ClientList = {}
Client.ClientList = {}
--- The Character that the client is currently controlling.
-- @treturn Character
-- @realm shared
Character = {}