Fix mixed spaces and tabs
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
@@ -14,40 +14,40 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class CsScriptBase : AssemblyLoadContext
|
||||
{
|
||||
class CsScriptBase : AssemblyLoadContext
|
||||
{
|
||||
|
||||
public const string CsOneTimeScriptAssembly = "NetOneTimeScriptAssembly";
|
||||
public const string CsScriptAssembly = "NetScriptAssembly";
|
||||
public const string CsOneTimeScriptAssembly = "NetOneTimeScriptAssembly";
|
||||
public const string CsScriptAssembly = "NetScriptAssembly";
|
||||
|
||||
public static readonly string[] LoadedAssemblyName = {
|
||||
CsScriptBase.CsScriptAssembly,
|
||||
CsScriptBase.CsOneTimeScriptAssembly
|
||||
};
|
||||
|
||||
public static Dictionary<string, object> Revision = new Dictionary<string, object>()
|
||||
{
|
||||
{ CsScriptAssembly, 0},
|
||||
{ CsOneTimeScriptAssembly, 0}
|
||||
public static readonly string[] LoadedAssemblyName = {
|
||||
CsScriptBase.CsScriptAssembly,
|
||||
CsScriptBase.CsOneTimeScriptAssembly
|
||||
};
|
||||
|
||||
public CSharpParseOptions ParseOptions { get; protected set; }
|
||||
|
||||
public CsScriptBase() : base(isCollectible: true) {
|
||||
ParseOptions = CSharpParseOptions.Default
|
||||
.WithPreprocessorSymbols(new[] { LuaCsSetup.IsServer ? "SERVER" : (LuaCsSetup.IsClient ? "CLIENT" : "UNDEFINED") });
|
||||
}
|
||||
|
||||
public static SyntaxTree AssemblyInfoSyntaxTree(string asmName = null)
|
||||
public static Dictionary<string, object> Revision = new Dictionary<string, object>()
|
||||
{
|
||||
Revision[asmName] = (int)Revision[asmName] + 1;
|
||||
var asmInfo = new StringBuilder();
|
||||
asmInfo.AppendLine("using System.Reflection;");
|
||||
asmInfo.AppendLine($"[assembly: AssemblyMetadata(\"Revision\", \"{Revision[asmName]}\")]");
|
||||
asmInfo.AppendLine($"[assembly: AssemblyVersion(\"0.0.0.{Revision[asmName]}\")]");
|
||||
return CSharpSyntaxTree.ParseText(asmInfo.ToString(), CSharpParseOptions.Default);
|
||||
}
|
||||
{ CsScriptAssembly, 0},
|
||||
{ CsOneTimeScriptAssembly, 0}
|
||||
};
|
||||
|
||||
~CsScriptBase() { }
|
||||
}
|
||||
}
|
||||
public CSharpParseOptions ParseOptions { get; protected set; }
|
||||
|
||||
public CsScriptBase() : base(isCollectible: true) {
|
||||
ParseOptions = CSharpParseOptions.Default
|
||||
.WithPreprocessorSymbols(new[] { LuaCsSetup.IsServer ? "SERVER" : (LuaCsSetup.IsClient ? "CLIENT" : "UNDEFINED") });
|
||||
}
|
||||
|
||||
public static SyntaxTree AssemblyInfoSyntaxTree(string asmName = null)
|
||||
{
|
||||
Revision[asmName] = (int)Revision[asmName] + 1;
|
||||
var asmInfo = new StringBuilder();
|
||||
asmInfo.AppendLine("using System.Reflection;");
|
||||
asmInfo.AppendLine($"[assembly: AssemblyMetadata(\"Revision\", \"{Revision[asmName]}\")]");
|
||||
asmInfo.AppendLine($"[assembly: AssemblyVersion(\"0.0.0.{Revision[asmName]}\")]");
|
||||
return CSharpSyntaxTree.ParseText(asmInfo.ToString(), CSharpParseOptions.Default);
|
||||
}
|
||||
|
||||
~CsScriptBase() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
@@ -14,208 +14,208 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class CsScriptLoader : CsScriptBase
|
||||
{
|
||||
private List<MetadataReference> defaultReferences;
|
||||
class CsScriptLoader : CsScriptBase
|
||||
{
|
||||
private List<MetadataReference> defaultReferences;
|
||||
|
||||
private Dictionary<string, List<string>> sources;
|
||||
public Assembly Assembly { get; private set; }
|
||||
private Dictionary<string, List<string>> sources;
|
||||
public Assembly Assembly { get; private set; }
|
||||
|
||||
public CsScriptLoader()
|
||||
{
|
||||
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();
|
||||
|
||||
sources = new Dictionary<string, List<string>>();
|
||||
Assembly = null;
|
||||
}
|
||||
|
||||
private enum RunType { Standard, Forced, None };
|
||||
private bool ShouldRun(ContentPackage cp, string path)
|
||||
{
|
||||
if (!Directory.Exists(path + "CSharp"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var isEnabled = ContentPackageManager.EnabledPackages.All.Contains(cp);
|
||||
if (File.Exists(path + "CSharp/RunConfig.xml"))
|
||||
{
|
||||
Stream stream = File.Open(path + "CSharp/RunConfig.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
var doc = XDocument.Load(stream);
|
||||
var elems = doc.Root.Elements().ToArray();
|
||||
var elem = elems.FirstOrDefault(e => e.Name.LocalName.Equals(LuaCsSetup.IsServer ? "Server" : (LuaCsSetup.IsClient ? "Client" : "None"), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (elem != null && Enum.TryParse(elem.Value, true, out RunType rtValue))
|
||||
{
|
||||
if (rtValue == RunType.Standard && isEnabled)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage($"Standard run C# of {cp.Name}");
|
||||
return true;
|
||||
}
|
||||
else if (rtValue == RunType.Forced)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage($"Forced run C# of {cp.Name}");
|
||||
return true;
|
||||
}
|
||||
else if (rtValue == RunType.None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage($"Assumed run C# of {cp.Name}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SearchFolders()
|
||||
{
|
||||
var paths = new Dictionary<string, string>();
|
||||
foreach (var cp in ContentPackageManager.AllPackages.Concat(ContentPackageManager.EnabledPackages.All))
|
||||
{
|
||||
var path = $"{Path.GetFullPath(Path.GetDirectoryName(cp.Path)).Replace('\\', '/')}/";
|
||||
if (ShouldRun(cp, path))
|
||||
{
|
||||
if (paths.ContainsKey(cp.Name))
|
||||
{
|
||||
if (ContentPackageManager.EnabledPackages.All.Contains(cp))
|
||||
{
|
||||
paths[cp.Name] = path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paths.Add(cp.Name, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((var _, var path) in paths)
|
||||
{
|
||||
RunFolder(path);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasSources { get => sources.Count > 0; }
|
||||
|
||||
private void AddSources(string folder)
|
||||
public CsScriptLoader()
|
||||
{
|
||||
foreach (var str in DirSearch(folder))
|
||||
{
|
||||
string s = str.Replace("\\", "/");
|
||||
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();
|
||||
|
||||
if (sources.ContainsKey(folder))
|
||||
{
|
||||
sources[folder].Add(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
sources.Add(folder, new List<string> { s });
|
||||
}
|
||||
}
|
||||
}
|
||||
sources = new Dictionary<string, List<string>>();
|
||||
Assembly = null;
|
||||
}
|
||||
|
||||
private void RunFolder(string folder)
|
||||
{
|
||||
|
||||
AddSources(folder + "/CSharp/Shared");
|
||||
|
||||
#if SERVER
|
||||
AddSources(folder + "/CSharp/Server");
|
||||
#else
|
||||
AddSources(folder + "/CSharp/Client");
|
||||
#endif
|
||||
}
|
||||
|
||||
private IEnumerable<SyntaxTree> ParseSources() {
|
||||
var syntaxTrees = new List<SyntaxTree>();
|
||||
|
||||
if (sources.Count <= 0) throw new Exception("No Cs sources detected");
|
||||
syntaxTrees.Add(AssemblyInfoSyntaxTree(CsScriptAssembly));
|
||||
foreach ((var folder, var src) in sources)
|
||||
private enum RunType { Standard, Forced, None };
|
||||
private bool ShouldRun(ContentPackage cp, string path)
|
||||
{
|
||||
if (!Directory.Exists(path + "CSharp"))
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var file in src)
|
||||
{
|
||||
var tree = SyntaxFactory.ParseSyntaxTree(File.ReadAllText(file), ParseOptions, file);
|
||||
|
||||
syntaxTrees.Add(tree);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LuaCsSetup.PrintCsError("Error loading '" + folder + "':\n" + ex.Message + "\n" + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
return syntaxTrees;
|
||||
}
|
||||
|
||||
public List<Type> Compile()
|
||||
{
|
||||
IEnumerable<SyntaxTree> syntaxTrees = ParseSources();
|
||||
|
||||
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
||||
.WithMetadataImportOptions(MetadataImportOptions.All)
|
||||
.WithOptimizationLevel(OptimizationLevel.Release)
|
||||
.WithAllowUnsafe(false);
|
||||
var compilation = CSharpCompilation.Create(CsScriptAssembly, 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 = "CS MODS NOT LOADED | Compilation errors:";
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
errStr += $"\n{diagnostic}";
|
||||
LuaCsSetup.PrintCsError(errStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
Assembly = LoadFromStream(mem);
|
||||
}
|
||||
}
|
||||
|
||||
if (Assembly != null)
|
||||
{
|
||||
return Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(ACsMod))).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unable to create cs mods assembly.");
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] DirSearch(string sDir)
|
||||
{
|
||||
if (!Directory.Exists(sDir))
|
||||
{
|
||||
return new string[] {};
|
||||
return false;
|
||||
}
|
||||
|
||||
return Directory.GetFiles(sDir, "*.cs", SearchOption.AllDirectories);
|
||||
}
|
||||
var isEnabled = ContentPackageManager.EnabledPackages.All.Contains(cp);
|
||||
if (File.Exists(path + "CSharp/RunConfig.xml"))
|
||||
{
|
||||
Stream stream = File.Open(path + "CSharp/RunConfig.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
var doc = XDocument.Load(stream);
|
||||
var elems = doc.Root.Elements().ToArray();
|
||||
var elem = elems.FirstOrDefault(e => e.Name.LocalName.Equals(LuaCsSetup.IsServer ? "Server" : (LuaCsSetup.IsClient ? "Client" : "None"), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Assembly = null;
|
||||
if (elem != null && Enum.TryParse(elem.Value, true, out RunType rtValue))
|
||||
{
|
||||
if (rtValue == RunType.Standard && isEnabled)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage($"Standard run C# of {cp.Name}");
|
||||
return true;
|
||||
}
|
||||
else if (rtValue == RunType.Forced)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage($"Forced run C# of {cp.Name}");
|
||||
return true;
|
||||
}
|
||||
else if (rtValue == RunType.None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
LuaCsSetup.PrintCsMessage($"Assumed run C# of {cp.Name}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SearchFolders()
|
||||
{
|
||||
var paths = new Dictionary<string, string>();
|
||||
foreach (var cp in ContentPackageManager.AllPackages.Concat(ContentPackageManager.EnabledPackages.All))
|
||||
{
|
||||
var path = $"{Path.GetFullPath(Path.GetDirectoryName(cp.Path)).Replace('\\', '/')}/";
|
||||
if (ShouldRun(cp, path))
|
||||
{
|
||||
if (paths.ContainsKey(cp.Name))
|
||||
{
|
||||
if (ContentPackageManager.EnabledPackages.All.Contains(cp))
|
||||
{
|
||||
paths[cp.Name] = path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paths.Add(cp.Name, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((var _, var path) in paths)
|
||||
{
|
||||
RunFolder(path);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasSources { get => sources.Count > 0; }
|
||||
|
||||
private void AddSources(string folder)
|
||||
{
|
||||
foreach (var str in DirSearch(folder))
|
||||
{
|
||||
string s = str.Replace("\\", "/");
|
||||
|
||||
if (sources.ContainsKey(folder))
|
||||
{
|
||||
sources[folder].Add(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
sources.Add(folder, new List<string> { s });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RunFolder(string folder)
|
||||
{
|
||||
|
||||
AddSources(folder + "/CSharp/Shared");
|
||||
|
||||
#if SERVER
|
||||
AddSources(folder + "/CSharp/Server");
|
||||
#else
|
||||
AddSources(folder + "/CSharp/Client");
|
||||
#endif
|
||||
}
|
||||
|
||||
private IEnumerable<SyntaxTree> ParseSources() {
|
||||
var syntaxTrees = new List<SyntaxTree>();
|
||||
|
||||
if (sources.Count <= 0) throw new Exception("No Cs sources detected");
|
||||
syntaxTrees.Add(AssemblyInfoSyntaxTree(CsScriptAssembly));
|
||||
foreach ((var folder, var src) in sources)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var file in src)
|
||||
{
|
||||
var tree = SyntaxFactory.ParseSyntaxTree(File.ReadAllText(file), ParseOptions, file);
|
||||
|
||||
syntaxTrees.Add(tree);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LuaCsSetup.PrintCsError("Error loading '" + folder + "':\n" + ex.Message + "\n" + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
return syntaxTrees;
|
||||
}
|
||||
|
||||
public List<Type> Compile()
|
||||
{
|
||||
IEnumerable<SyntaxTree> syntaxTrees = ParseSources();
|
||||
|
||||
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
||||
.WithMetadataImportOptions(MetadataImportOptions.All)
|
||||
.WithOptimizationLevel(OptimizationLevel.Release)
|
||||
.WithAllowUnsafe(false);
|
||||
var compilation = CSharpCompilation.Create(CsScriptAssembly, 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 = "CS MODS NOT LOADED | Compilation errors:";
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
errStr += $"\n{diagnostic}";
|
||||
LuaCsSetup.PrintCsError(errStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
Assembly = LoadFromStream(mem);
|
||||
}
|
||||
}
|
||||
|
||||
if (Assembly != null)
|
||||
{
|
||||
return Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(ACsMod))).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unable to create cs mods assembly.");
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] DirSearch(string sDir)
|
||||
{
|
||||
if (!Directory.Exists(sDir))
|
||||
{
|
||||
return new string[] {};
|
||||
}
|
||||
|
||||
return Directory.GetFiles(sDir, "*.cs", SearchOption.AllDirectories);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Assembly = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
@@ -13,109 +13,109 @@ using MoonSharp.Interpreter;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class CsScriptRunner : CsScriptBase
|
||||
{
|
||||
public LuaCsSetup setup;
|
||||
private List<MetadataReference> defaultReferences;
|
||||
private CSharpCompilationOptions compileOptions;
|
||||
private static readonly string[] usings = {
|
||||
"System",
|
||||
"Barotrauma",
|
||||
"System.Collections.Generic",
|
||||
"System.Linq"
|
||||
};
|
||||
class CsScriptRunner : CsScriptBase
|
||||
{
|
||||
public LuaCsSetup setup;
|
||||
private List<MetadataReference> defaultReferences;
|
||||
private CSharpCompilationOptions compileOptions;
|
||||
private static readonly string[] usings = {
|
||||
"System",
|
||||
"Barotrauma",
|
||||
"System.Collections.Generic",
|
||||
"System.Linq"
|
||||
};
|
||||
|
||||
public CsScriptRunner(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();
|
||||
compileOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
||||
.WithMetadataImportOptions(MetadataImportOptions.All)
|
||||
.WithOptimizationLevel(OptimizationLevel.Release)
|
||||
.WithAllowUnsafe(false);
|
||||
}
|
||||
|
||||
private static string ToOneTimeScript(string code)
|
||||
public CsScriptRunner(LuaCsSetup setup)
|
||||
{
|
||||
var prefix = "";
|
||||
foreach (var u in usings) prefix += $"using {u}; ";
|
||||
prefix += "namespace NetOneTimeScript { public class NetOneTimeScriptRunner { public NetOneTimeScriptRunner() { } public object Run() {\n";
|
||||
var postfix = "\nreturn null; } } }";
|
||||
return prefix + code + postfix;
|
||||
}
|
||||
this.setup = setup;
|
||||
|
||||
public object Run(string code)
|
||||
{
|
||||
object scriptResilt = null;
|
||||
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();
|
||||
compileOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
||||
.WithMetadataImportOptions(MetadataImportOptions.All)
|
||||
.WithOptimizationLevel(OptimizationLevel.Release)
|
||||
.WithAllowUnsafe(false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
code = ToOneTimeScript(code);
|
||||
var syntaxTree = SyntaxFactory.ParseSyntaxTree(code, ParseOptions);
|
||||
var compilation = CSharpCompilation.Create(CsOneTimeScriptAssembly, new[] { AssemblyInfoSyntaxTree(CsOneTimeScriptAssembly), syntaxTree }, defaultReferences, compileOptions);
|
||||
private static string ToOneTimeScript(string code)
|
||||
{
|
||||
var prefix = "";
|
||||
foreach (var u in usings) prefix += $"using {u}; ";
|
||||
prefix += "namespace NetOneTimeScript { public class NetOneTimeScriptRunner { public NetOneTimeScriptRunner() { } public object Run() {\n";
|
||||
var postfix = "\nreturn null; } } }";
|
||||
return prefix + code + postfix;
|
||||
}
|
||||
|
||||
Assembly assembly = null;
|
||||
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);
|
||||
public object Run(string code)
|
||||
{
|
||||
object scriptResilt = null;
|
||||
|
||||
string errStr = "Script compilation errors:";
|
||||
var lineErr = new SortedDictionary<int, (string, string)>();
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
try
|
||||
{
|
||||
code = ToOneTimeScript(code);
|
||||
var syntaxTree = SyntaxFactory.ParseSyntaxTree(code, ParseOptions);
|
||||
var compilation = CSharpCompilation.Create(CsOneTimeScriptAssembly, new[] { AssemblyInfoSyntaxTree(CsOneTimeScriptAssembly), syntaxTree }, defaultReferences, compileOptions);
|
||||
|
||||
Assembly assembly = null;
|
||||
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 = "Script compilation errors:";
|
||||
var lineErr = new SortedDictionary<int, (string, string)>();
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
{
|
||||
var line = syntaxTree.GetLineSpan(diagnostic.Location.SourceSpan).StartLinePosition.Line;
|
||||
lineErr[line] = (diagnostic.Id, diagnostic.ToString());
|
||||
}
|
||||
var lines = code.Split('\n');
|
||||
for (var i = 1; i < lines.Length - 1; i++)
|
||||
var line = syntaxTree.GetLineSpan(diagnostic.Location.SourceSpan).StartLinePosition.Line;
|
||||
lineErr[line] = (diagnostic.Id, diagnostic.ToString());
|
||||
}
|
||||
var lines = code.Split('\n');
|
||||
for (var i = 1; i < lines.Length - 1; i++)
|
||||
{
|
||||
errStr += $"\n{i} >> {lines[i]}";
|
||||
if (lineErr.ContainsKey(i)) errStr += $" <=== {lineErr[i].Item1}";
|
||||
}
|
||||
errStr += "\n";
|
||||
foreach ((var idx, (var id, var err)) in lineErr)
|
||||
errStr += $"\n{i} >> {lines[i]}";
|
||||
if (lineErr.ContainsKey(i)) errStr += $" <=== {lineErr[i].Item1}";
|
||||
}
|
||||
errStr += "\n";
|
||||
foreach ((var idx, (var id, var err)) in lineErr)
|
||||
{
|
||||
errStr += $"\n{idx}: {err}";
|
||||
}
|
||||
LuaCsSetup.PrintCsError(errStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
assembly = LoadFromStream(mem);
|
||||
var runner = assembly.CreateInstance("NetOneTimeScript.NetOneTimeScriptRunner");
|
||||
if (runner != null)
|
||||
{
|
||||
var method = runner.GetType().GetMethod("Run", BindingFlags.Public | BindingFlags.Instance);
|
||||
if (method != null)
|
||||
{
|
||||
scriptResilt = method.Invoke(runner, null);
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
UserData.UnregisterType(type, true);
|
||||
}
|
||||
}
|
||||
else { LuaCsSetup.PrintCsError("Script Error - no run method detected"); }
|
||||
}
|
||||
else { LuaCsSetup.PrintCsError("Script Error - no runner class detected"); }
|
||||
}
|
||||
}
|
||||
Unload();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LuaCsSetup.PrintCsError("Error running script:\n" + ex.Message + "\n" + ex.StackTrace);
|
||||
}
|
||||
errStr += $"\n{idx}: {err}";
|
||||
}
|
||||
LuaCsSetup.PrintCsError(errStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
assembly = LoadFromStream(mem);
|
||||
var runner = assembly.CreateInstance("NetOneTimeScript.NetOneTimeScriptRunner");
|
||||
if (runner != null)
|
||||
{
|
||||
var method = runner.GetType().GetMethod("Run", BindingFlags.Public | BindingFlags.Instance);
|
||||
if (method != null)
|
||||
{
|
||||
scriptResilt = method.Invoke(runner, null);
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
UserData.UnregisterType(type, true);
|
||||
}
|
||||
}
|
||||
else { LuaCsSetup.PrintCsError("Script Error - no run method detected"); }
|
||||
}
|
||||
else { LuaCsSetup.PrintCsError("Script Error - no runner class detected"); }
|
||||
}
|
||||
}
|
||||
Unload();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LuaCsSetup.PrintCsError("Error running script:\n" + ex.Message + "\n" + ex.StackTrace);
|
||||
}
|
||||
|
||||
return scriptResilt;
|
||||
}
|
||||
return scriptResilt;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,19 @@ using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class Client
|
||||
{
|
||||
public static IReadOnlyList<Client> ClientList
|
||||
{
|
||||
get
|
||||
{
|
||||
partial class Client
|
||||
{
|
||||
public static IReadOnlyList<Client> ClientList
|
||||
{
|
||||
get
|
||||
{
|
||||
#if SERVER
|
||||
return GameMain.Server.ConnectedClients;
|
||||
return GameMain.Server.ConnectedClients;
|
||||
#else
|
||||
return GameMain.Client.ConnectedClients;
|
||||
return GameMain.Client.ConnectedClients;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ulong SteamID
|
||||
{
|
||||
@@ -36,71 +36,71 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
using Barotrauma.Networking;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Barotrauma.Networking;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
|
||||
partial class Character
|
||||
{
|
||||
|
||||
}
|
||||
partial class Character
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
partial class Item
|
||||
{
|
||||
public object GetComponentString(string component)
|
||||
{
|
||||
Type type = Type.GetType("Barotrauma.Items.Components." + component);
|
||||
partial class Item
|
||||
{
|
||||
public object GetComponentString(string component)
|
||||
{
|
||||
Type type = Type.GetType("Barotrauma.Items.Components." + component);
|
||||
|
||||
if (type == null)
|
||||
return null;
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
MethodInfo method = typeof(Item).GetMethod(nameof(Item.GetComponent));
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(this, null);
|
||||
}
|
||||
MethodInfo method = typeof(Item).GetMethod(nameof(Item.GetComponent));
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(this, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
partial class ItemPrefab
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return itemPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
abstract partial class MapEntity
|
||||
{
|
||||
public void AddLinked(MapEntity entity)
|
||||
{
|
||||
linkedTo.Add(entity);
|
||||
}
|
||||
}
|
||||
abstract partial class MapEntity
|
||||
{
|
||||
public void AddLinked(MapEntity entity)
|
||||
{
|
||||
linkedTo.Add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
partial class CustomInterface
|
||||
{
|
||||
}
|
||||
partial class CustomInterface
|
||||
{
|
||||
}
|
||||
|
||||
partial struct Signal
|
||||
{
|
||||
}
|
||||
partial struct Signal
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,86 +10,86 @@ using MoonSharp.Interpreter;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaGame
|
||||
{
|
||||
public bool IsSingleplayer => GameMain.IsSingleplayer;
|
||||
public bool IsMultiplayer => GameMain.IsMultiplayer;
|
||||
public string SaveFolder => SaveUtil.SaveFolder;
|
||||
partial class LuaGame
|
||||
{
|
||||
public bool IsSingleplayer => GameMain.IsSingleplayer;
|
||||
public bool IsMultiplayer => GameMain.IsMultiplayer;
|
||||
public string SaveFolder => SaveUtil.SaveFolder;
|
||||
|
||||
#if CLIENT
|
||||
public GameClient Client
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Client;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Paused => GameMain.Instance?.Paused == true;
|
||||
public byte SessionId => GameMain.Client.SessionId;
|
||||
public byte MyID => SessionId; // compatibility
|
||||
|
||||
public ChatMode ActiveChatMode => GameMain.ActiveChatMode;
|
||||
|
||||
public ChatBox ChatBox
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GameMain.IsSingleplayer)
|
||||
return GameMain.GameSession.CrewManager.ChatBox;
|
||||
else
|
||||
return GameMain.Client.ChatBox;
|
||||
}
|
||||
}
|
||||
|
||||
public Sounds.SoundManager SoundManager
|
||||
public GameClient Client
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.SoundManager;
|
||||
return GameMain.Client;
|
||||
}
|
||||
}
|
||||
|
||||
public Lights.LightManager LightManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.LightManager;
|
||||
}
|
||||
}
|
||||
public bool Paused => GameMain.Instance?.Paused == true;
|
||||
public byte SessionId => GameMain.Client.SessionId;
|
||||
public byte MyID => SessionId; // compatibility
|
||||
|
||||
public SubEditorScreen SubEditorScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.SubEditorScreen;
|
||||
}
|
||||
}
|
||||
public ChatMode ActiveChatMode => GameMain.ActiveChatMode;
|
||||
|
||||
public bool IsSubEditor
|
||||
public ChatBox ChatBox
|
||||
{
|
||||
get
|
||||
{
|
||||
return Screen.Selected is SubEditorScreen;
|
||||
if (GameMain.IsSingleplayer)
|
||||
return GameMain.GameSession.CrewManager.ChatBox;
|
||||
else
|
||||
return GameMain.Client.ChatBox;
|
||||
}
|
||||
}
|
||||
|
||||
public Sounds.SoundManager SoundManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.SoundManager;
|
||||
}
|
||||
}
|
||||
|
||||
public Lights.LightManager LightManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.LightManager;
|
||||
}
|
||||
}
|
||||
|
||||
public SubEditorScreen SubEditorScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.SubEditorScreen;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSubEditor
|
||||
{
|
||||
get
|
||||
{
|
||||
return Screen.Selected is SubEditorScreen;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
public GameServer Server
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server;
|
||||
}
|
||||
}
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDedicated
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server.ServerPeer is LidgrenServerPeer;
|
||||
}
|
||||
}
|
||||
public bool IsDedicated
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server.ServerPeer is LidgrenServerPeer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public ServerSettings ServerSettings
|
||||
@@ -121,296 +121,296 @@ namespace Barotrauma
|
||||
|
||||
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 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 poweredUpdateInterval
|
||||
{
|
||||
get { return MapEntity.PoweredUpdateInterval; }
|
||||
set { MapEntity.PoweredUpdateInterval = 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 == true;
|
||||
#else
|
||||
return GameMain.Client?.GameStarted == true;
|
||||
#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()
|
||||
public int mapEntityUpdateInterval
|
||||
{
|
||||
LuaUserData.MakeFieldAccessible(UserData.RegisterType(typeof(GameSettings)), "currentConfig");
|
||||
Settings = UserData.CreateStatic(typeof(GameSettings));
|
||||
get { return MapEntity.MapEntityUpdateInterval; }
|
||||
set { MapEntity.MapEntityUpdateInterval = value; }
|
||||
}
|
||||
|
||||
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()
|
||||
public int gapUpdateInterval
|
||||
{
|
||||
return ContentPackageManager.EnabledPackages.All.ToArray();
|
||||
get { return MapEntity.GapUpdateInterval; }
|
||||
set { MapEntity.GapUpdateInterval = value; }
|
||||
}
|
||||
|
||||
public static ItemPrefab GetItemPrefab(string itemNameOrId)
|
||||
{
|
||||
ItemPrefab itemPrefab =
|
||||
(MapEntityPrefab.Find(itemNameOrId, identifier: null, showErrorMessages: false) ??
|
||||
MapEntityPrefab.Find(null, identifier: itemNameOrId, showErrorMessages: false)) as ItemPrefab;
|
||||
public int poweredUpdateInterval
|
||||
{
|
||||
get { return MapEntity.PoweredUpdateInterval; }
|
||||
set { MapEntity.PoweredUpdateInterval = value; }
|
||||
}
|
||||
|
||||
return itemPrefab;
|
||||
}
|
||||
public int characterUpdateInterval
|
||||
{
|
||||
get { return Character.CharacterUpdateInterval; }
|
||||
set { Character.CharacterUpdateInterval = value; }
|
||||
}
|
||||
|
||||
public static Submarine GetRespawnSub()
|
||||
{
|
||||
|
||||
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
|
||||
if (GameMain.Server.RespawnManager == null)
|
||||
return null;
|
||||
return GameMain.Server.RespawnManager.RespawnShuttle;
|
||||
return GameMain.Server?.GameStarted == true;
|
||||
#else
|
||||
if (GameMain.Client.RespawnManager == null)
|
||||
return null;
|
||||
return GameMain.Client.RespawnManager.RespawnShuttle;
|
||||
return GameMain.Client?.GameStarted == true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Items.Components.Steering GetSubmarineSteering(Submarine sub)
|
||||
{
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != sub) continue;
|
||||
public GameSession GameSession
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.GameSession;
|
||||
}
|
||||
}
|
||||
|
||||
var steering = item.GetComponent<Items.Components.Steering>();
|
||||
if (steering != null)
|
||||
{
|
||||
return steering;
|
||||
}
|
||||
}
|
||||
public NetLobbyScreen NetLobbyScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.NetLobbyScreen;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public GameScreen GameScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.GameScreen;
|
||||
}
|
||||
}
|
||||
|
||||
public static WifiComponent GetWifiComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<WifiComponent>();
|
||||
}
|
||||
public World World
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.World;
|
||||
}
|
||||
}
|
||||
|
||||
public static LightComponent GetLightComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<LightComponent>();
|
||||
}
|
||||
#if SERVER
|
||||
public ServerPeer Peer
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Server.ServerPeer;
|
||||
}
|
||||
}
|
||||
#else
|
||||
public ClientPeer Peer
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.Client.ClientPeer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static CustomInterface GetCustomInterface(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<CustomInterface>();
|
||||
}
|
||||
public LuaGame()
|
||||
{
|
||||
LuaUserData.MakeFieldAccessible(UserData.RegisterType(typeof(GameSettings)), "currentConfig");
|
||||
Settings = UserData.CreateStatic(typeof(GameSettings));
|
||||
}
|
||||
|
||||
public static Fabricator GetFabricatorComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<Fabricator>();
|
||||
}
|
||||
public void OverrideTraitors(bool o)
|
||||
{
|
||||
overrideTraitors = o;
|
||||
}
|
||||
|
||||
public static Holdable GetHoldableComponent(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
return item.GetComponent<Holdable>();
|
||||
}
|
||||
public void OverrideRespawnSub(bool o)
|
||||
{
|
||||
overrideRespawnSub = o;
|
||||
}
|
||||
|
||||
public static void ExecuteCommand(string command)
|
||||
{
|
||||
DebugConsole.ExecuteCommand(command);
|
||||
}
|
||||
public void AllowWifiChat(bool o)
|
||||
{
|
||||
allowWifiChat = o;
|
||||
}
|
||||
|
||||
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 void OverrideSignalRadio(bool o)
|
||||
{
|
||||
overrideSignalRadio = o;
|
||||
}
|
||||
|
||||
private List<DebugConsole.Command> luaAddedCommand = new List<DebugConsole.Command>();
|
||||
public void DisableSpamFilter(bool o)
|
||||
{
|
||||
disableSpamFilter = o;
|
||||
}
|
||||
|
||||
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 DisableDisconnectCharacter(bool o)
|
||||
{
|
||||
disableDisconnectCharacter = o;
|
||||
}
|
||||
|
||||
public void AddCommand(string name, string help, LuaCsAction onExecute, LuaCsFunc getValidArgs = null, bool isCheat = false)
|
||||
{
|
||||
var cmd = new DebugConsole.Command(name, help, (string[] arg1) => onExecute(new object[] { arg1 }),
|
||||
() =>
|
||||
{
|
||||
if (getValidArgs == null) return null;
|
||||
|
||||
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, LuaCsAction onExecute, LuaCsFunc getValidArgs = null, bool isCheat = false)
|
||||
{
|
||||
var cmd = new DebugConsole.Command(name, help, (string[] arg1) => onExecute(new object[] { arg1 }),
|
||||
() =>
|
||||
{
|
||||
if (getValidArgs == null) return null;
|
||||
var validArgs = getValidArgs();
|
||||
if (validArgs is DynValue luaValue)
|
||||
{
|
||||
@@ -419,96 +419,96 @@ namespace Barotrauma
|
||||
return (string[][])validArgs;
|
||||
}, isCheat);
|
||||
|
||||
luaAddedCommand.Add(cmd);
|
||||
DebugConsole.Commands.Add(cmd);
|
||||
}
|
||||
|
||||
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 }); });
|
||||
|
||||
public void SaveGame(string path)
|
||||
{
|
||||
if (!LuaCsFile.CanWriteToPath(path)) { throw new ScriptRuntimeException($"Saving files to {path} is disallowed."); }
|
||||
SaveUtil.SaveGame(path);
|
||||
luaAddedCommand.Add(cmd);
|
||||
DebugConsole.Commands.Add(cmd);
|
||||
}
|
||||
|
||||
public void LoadGame(string path)
|
||||
{
|
||||
SaveUtil.LoadGame(path);
|
||||
}
|
||||
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 }); });
|
||||
|
||||
public void SaveGame(string path)
|
||||
{
|
||||
if (!LuaCsFile.CanWriteToPath(path)) { throw new ScriptRuntimeException($"Saving files to {path} is disallowed."); }
|
||||
SaveUtil.SaveGame(path);
|
||||
}
|
||||
|
||||
public void LoadGame(string path)
|
||||
{
|
||||
SaveUtil.LoadGame(path);
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
public void LoadCampaign(string path)
|
||||
{
|
||||
MultiPlayerCampaign.LoadCampaign(path);
|
||||
}
|
||||
public void LoadCampaign(string path)
|
||||
{
|
||||
MultiPlayerCampaign.LoadCampaign(path);
|
||||
}
|
||||
|
||||
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, 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 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 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 = "")
|
||||
{
|
||||
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;
|
||||
ChatMessage cm = ChatMessage.Create(sendername, text, messageType, sender, client);
|
||||
cm.IconStyle = iconStyle;
|
||||
|
||||
GameMain.Server.SendDirectChatMessage(cm, client);
|
||||
GameMain.Server.SendDirectChatMessage(cm, client);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void SendDirectChatMessage(ChatMessage chatMessage, Client client)
|
||||
{
|
||||
GameMain.Server.SendDirectChatMessage(chatMessage, 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 Log(string message, ServerLog.MessageType type)
|
||||
{
|
||||
GameServer.Log(message, type);
|
||||
}
|
||||
|
||||
public static void DispatchRespawnSub()
|
||||
{
|
||||
GameMain.Server.RespawnManager.DispatchShuttle();
|
||||
}
|
||||
public static void DispatchRespawnSub()
|
||||
{
|
||||
GameMain.Server.RespawnManager.DispatchShuttle();
|
||||
}
|
||||
|
||||
public static void StartGame()
|
||||
{
|
||||
GameMain.Server.StartGame();
|
||||
}
|
||||
public static void StartGame()
|
||||
{
|
||||
GameMain.Server.StartGame();
|
||||
}
|
||||
|
||||
public static void EndGame()
|
||||
{
|
||||
GameMain.Server.EndGame();
|
||||
}
|
||||
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 }); });
|
||||
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;
|
||||
public void Stop()
|
||||
{
|
||||
mapEntityUpdateInterval = 1;
|
||||
gapUpdateInterval = 4;
|
||||
characterUpdateInterval = 1;
|
||||
|
||||
foreach (var cmd in luaAddedCommand)
|
||||
{
|
||||
DebugConsole.Commands.Remove(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var cmd in luaAddedCommand)
|
||||
{
|
||||
DebugConsole.Commands.Remove(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,265 +7,265 @@ using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaUserData
|
||||
{
|
||||
public static Type GetType(string typeName)
|
||||
{
|
||||
partial class LuaUserData
|
||||
{
|
||||
public static Type GetType(string typeName)
|
||||
{
|
||||
if (typeName == null || typeName.Length == 0) return null;
|
||||
|
||||
var byRef = false;
|
||||
var byRef = false;
|
||||
if (typeName.StartsWith("out ") || typeName.StartsWith("ref "))
|
||||
{
|
||||
typeName = typeName.Remove(0, 4);
|
||||
byRef = true;
|
||||
}
|
||||
{
|
||||
typeName = typeName.Remove(0, 4);
|
||||
byRef = true;
|
||||
}
|
||||
|
||||
var type = Type.GetType(typeName);
|
||||
if (type != null) return byRef ? type.MakeByRefType() : type;
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (CsScriptBase.LoadedAssemblyName.Contains(a.GetName().Name))
|
||||
{
|
||||
var attrs = a.GetCustomAttributes<AssemblyMetadataAttribute>();
|
||||
var revision = attrs.FirstOrDefault(attr => attr.Key == "Revision")?.Value;
|
||||
if (revision != null && int.Parse(revision) != (int)CsScriptBase.Revision[a.GetName().Name]) { continue; }
|
||||
}
|
||||
type = a.GetType(typeName);
|
||||
if (type != null)
|
||||
{
|
||||
return byRef ? type.MakeByRefType() : type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var type = Type.GetType(typeName);
|
||||
if (type != null) return byRef ? type.MakeByRefType() : type;
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (CsScriptBase.LoadedAssemblyName.Contains(a.GetName().Name))
|
||||
{
|
||||
var attrs = a.GetCustomAttributes<AssemblyMetadataAttribute>();
|
||||
var revision = attrs.FirstOrDefault(attr => attr.Key == "Revision")?.Value;
|
||||
if (revision != null && int.Parse(revision) != (int)CsScriptBase.Revision[a.GetName().Name]) { continue; }
|
||||
}
|
||||
type = a.GetType(typeName);
|
||||
if (type != null)
|
||||
{
|
||||
return byRef ? type.MakeByRefType() : type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IUserDataDescriptor RegisterType(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to register a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
return UserData.RegisterType(type);
|
||||
}
|
||||
|
||||
public static void UnregisterType(string typeName, bool deleteHistory = false)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to unregister a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
UserData.UnregisterType(type, deleteHistory);
|
||||
}
|
||||
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)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to create a static userdata of a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(null, null);
|
||||
}
|
||||
|
||||
public static object CreateEnumTable(string typeName)
|
||||
public static IUserDataDescriptor RegisterType(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to create an enum table with a type that doesn't exist:: {typeName}.");
|
||||
}
|
||||
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
foreach (var value in Enum.GetValues(type))
|
||||
if (type == null)
|
||||
{
|
||||
string name = Enum.GetName(type, value);
|
||||
|
||||
result[name] = value;
|
||||
throw new ScriptRuntimeException($"Tried to register a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return UserData.RegisterType(type);
|
||||
}
|
||||
|
||||
private static FieldInfo FindFieldRecursively(Type type, string fieldName)
|
||||
public static void UnregisterType(string typeName, bool deleteHistory = false)
|
||||
{
|
||||
var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
Type type = GetType(typeName);
|
||||
|
||||
if (field == null && type.BaseType != null)
|
||||
if (type == null)
|
||||
{
|
||||
return FindFieldRecursively(type.BaseType, fieldName);
|
||||
throw new ScriptRuntimeException($"Tried to unregister a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
UserData.UnregisterType(type, deleteHistory);
|
||||
}
|
||||
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 MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to make {fieldName} accessible.");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
var field = IUUD.Type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
private static bool IsType<T>(object obj) { return obj is T; }
|
||||
|
||||
if (field == null)
|
||||
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)
|
||||
{
|
||||
field = FindFieldRecursively(IUUD.Type, fieldName);
|
||||
throw new ScriptRuntimeException($"Tried to create a static userdata of a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
if (field == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to make field '{fieldName}' accessible, but the field doesn't exist.");
|
||||
}
|
||||
MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(null, null);
|
||||
}
|
||||
|
||||
descriptor.RemoveMember(fieldName);
|
||||
descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
|
||||
}
|
||||
public static object CreateEnumTable(string typeName)
|
||||
{
|
||||
Type type = GetType(typeName);
|
||||
|
||||
private static MethodInfo FindMethodRecursively(Type type, string methodName)
|
||||
{
|
||||
var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
if (type == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to create an enum table with a type that doesn't exist:: {typeName}.");
|
||||
}
|
||||
|
||||
if (method == null && type.BaseType != null)
|
||||
{
|
||||
return FindMethodRecursively(type.BaseType, methodName);
|
||||
}
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
return method;
|
||||
}
|
||||
foreach (var value in Enum.GetValues(type))
|
||||
{
|
||||
string name = Enum.GetName(type, value);
|
||||
|
||||
public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to make {methodName} accessible.");
|
||||
}
|
||||
result[name] = value;
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
var method = IUUD.Type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
method = FindMethodRecursively(IUUD.Type, methodName);
|
||||
}
|
||||
private static FieldInfo FindFieldRecursively(Type type, string fieldName)
|
||||
{
|
||||
var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to make method '{methodName}' accessible, but the method doesn't exist.");
|
||||
}
|
||||
if (field == null && type.BaseType != null)
|
||||
{
|
||||
return FindFieldRecursively(type.BaseType, fieldName);
|
||||
}
|
||||
|
||||
descriptor.RemoveMember(methodName);
|
||||
descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to add method {methodName}.");
|
||||
}
|
||||
public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to make {fieldName} accessible.");
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
var field = IUUD.Type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
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;
|
||||
}));
|
||||
}
|
||||
if (field == null)
|
||||
{
|
||||
field = FindFieldRecursively(IUUD.Type, fieldName);
|
||||
}
|
||||
|
||||
public static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to add field {fieldName}.");
|
||||
}
|
||||
if (field == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to make field '{fieldName}' accessible, but the field doesn't exist.");
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
descriptor.RemoveMember(fieldName);
|
||||
descriptor.AddMember(fieldName, new DynValueMemberDescriptor(fieldName, value));
|
||||
}
|
||||
descriptor.RemoveMember(fieldName);
|
||||
descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
|
||||
}
|
||||
|
||||
public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to remove the member {memberName}.");
|
||||
}
|
||||
private static MethodInfo FindMethodRecursively(Type type, string methodName)
|
||||
{
|
||||
var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
descriptor.RemoveMember(memberName);
|
||||
}
|
||||
if (method == null && type.BaseType != null)
|
||||
{
|
||||
return FindMethodRecursively(type.BaseType, methodName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="CreateUserDataFromType"/>.
|
||||
/// </summary>
|
||||
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
|
||||
/// <param name="desiredTypeDescriptor">Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters.</param>
|
||||
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type as described by <paramref name="desiredTypeDescriptor"/>.</returns>
|
||||
public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
|
||||
{
|
||||
return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata.
|
||||
/// If the type is not registered, then a new <see cref="MoonSharp.Interpreter.Interop.StandardUserDataDescriptor"/> will be created and used.
|
||||
/// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types.
|
||||
/// <remarks>Wrapping the value in a userdata preserves the original type during script-to-CLR conversions.</remarks>
|
||||
/// <example>A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets
|
||||
/// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything.
|
||||
/// Registering the List`1 type can break other scripts relying on default converters, so instead
|
||||
/// it is better to manually wrap the List`1 object into a userdata.
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
|
||||
/// <param name="desiredType">Type describing the CLR type of the object to convert the Lua value to.</param>
|
||||
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type.</returns>
|
||||
public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
|
||||
{
|
||||
IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
|
||||
descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
|
||||
return CreateUserDataFromDescriptor(scriptObject, descriptor);
|
||||
}
|
||||
}
|
||||
public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to make {methodName} accessible.");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to make method '{methodName}' accessible, but the method doesn't exist.");
|
||||
}
|
||||
|
||||
descriptor.RemoveMember(methodName);
|
||||
descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
|
||||
}
|
||||
|
||||
public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to add method {methodName}.");
|
||||
}
|
||||
|
||||
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 AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to add field {fieldName}.");
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
descriptor.RemoveMember(fieldName);
|
||||
descriptor.AddMember(fieldName, new DynValueMemberDescriptor(fieldName, value));
|
||||
}
|
||||
|
||||
public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
|
||||
{
|
||||
if (IUUD == null)
|
||||
{
|
||||
throw new ScriptRuntimeException($"Tried to use a UserDataDescriptor that is null to remove the member {memberName}.");
|
||||
}
|
||||
|
||||
var descriptor = (StandardUserDataDescriptor)IUUD;
|
||||
descriptor.RemoveMember(memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="CreateUserDataFromType"/>.
|
||||
/// </summary>
|
||||
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
|
||||
/// <param name="desiredTypeDescriptor">Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters.</param>
|
||||
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type as described by <paramref name="desiredTypeDescriptor"/>.</returns>
|
||||
public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
|
||||
{
|
||||
return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata.
|
||||
/// If the type is not registered, then a new <see cref="MoonSharp.Interpreter.Interop.StandardUserDataDescriptor"/> will be created and used.
|
||||
/// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types.
|
||||
/// <remarks>Wrapping the value in a userdata preserves the original type during script-to-CLR conversions.</remarks>
|
||||
/// <example>A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets
|
||||
/// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything.
|
||||
/// Registering the List`1 type can break other scripts relying on default converters, so instead
|
||||
/// it is better to manually wrap the List`1 object into a userdata.
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
|
||||
/// <param name="desiredType">Type describing the CLR type of the object to convert the Lua value to.</param>
|
||||
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type.</returns>
|
||||
public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
|
||||
{
|
||||
IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
|
||||
descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
|
||||
return CreateUserDataFromDescriptor(scriptObject, descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,21 +8,21 @@ using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class LuaScriptLoader : ScriptLoaderBase
|
||||
{
|
||||
class LuaScriptLoader : ScriptLoaderBase
|
||||
{
|
||||
|
||||
public override object LoadFile(string file, Table globalContext)
|
||||
{
|
||||
if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return null;
|
||||
|
||||
return File.ReadAllText(file);
|
||||
}
|
||||
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;
|
||||
public override bool ScriptFileExists(string file)
|
||||
{
|
||||
if (!LuaCsFile.IsPathAllowedLuaException(file, false)) return false;
|
||||
|
||||
return File.Exists(file);
|
||||
}
|
||||
return File.Exists(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,229 +8,229 @@ using LuaCsCompatPatchFunc = Barotrauma.LuaCsPatch;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
// XXX: this can't be renamed because of backward compatibility with C# mods
|
||||
public delegate object LuaCsPatch(object self, Dictionary<string, object> args);
|
||||
// XXX: this can't be renamed because of backward compatibility with C# mods
|
||||
public delegate object LuaCsPatch(object self, Dictionary<string, object> args);
|
||||
|
||||
partial class LuaCsHook
|
||||
partial class LuaCsHook
|
||||
{
|
||||
private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>> compatHookPrefixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>>();
|
||||
private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>> compatHookPostfixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>>();
|
||||
private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>> compatHookPrefixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>>();
|
||||
private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>> compatHookPostfixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>>();
|
||||
|
||||
private static void _hookLuaCsPatch(MethodBase __originalMethod, object[] __args, object __instance, out object result, HookMethodType hookType)
|
||||
{
|
||||
result = null;
|
||||
private static void _hookLuaCsPatch(MethodBase __originalMethod, object[] __args, object __instance, out object result, HookMethodType hookType)
|
||||
{
|
||||
result = null;
|
||||
|
||||
try
|
||||
{
|
||||
var funcAddr = ((long)__originalMethod.MethodHandle.GetFunctionPointer());
|
||||
HashSet<(string, LuaCsCompatPatchFunc, ACsMod)> methodSet = null;
|
||||
switch (hookType)
|
||||
{
|
||||
case HookMethodType.Before:
|
||||
instance.compatHookPrefixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
break;
|
||||
case HookMethodType.After:
|
||||
instance.compatHookPostfixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"Invalid {nameof(HookMethodType)} enum value.", nameof(hookType));
|
||||
}
|
||||
try
|
||||
{
|
||||
var funcAddr = ((long)__originalMethod.MethodHandle.GetFunctionPointer());
|
||||
HashSet<(string, LuaCsCompatPatchFunc, ACsMod)> methodSet = null;
|
||||
switch (hookType)
|
||||
{
|
||||
case HookMethodType.Before:
|
||||
instance.compatHookPrefixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
break;
|
||||
case HookMethodType.After:
|
||||
instance.compatHookPostfixMethods.TryGetValue(funcAddr, out methodSet);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"Invalid {nameof(HookMethodType)} enum value.", nameof(hookType));
|
||||
}
|
||||
|
||||
if (methodSet != null)
|
||||
{
|
||||
var @params = __originalMethod.GetParameters();
|
||||
var args = new Dictionary<string, object>();
|
||||
for (int i = 0; i < @params.Length; i++)
|
||||
{
|
||||
args.Add(@params[i].Name, __args[i]);
|
||||
}
|
||||
if (methodSet != null)
|
||||
{
|
||||
var @params = __originalMethod.GetParameters();
|
||||
var args = new Dictionary<string, object>();
|
||||
for (int i = 0; i < @params.Length; i++)
|
||||
{
|
||||
args.Add(@params[i].Name, __args[i]);
|
||||
}
|
||||
|
||||
var outOfSocpe = new HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>();
|
||||
foreach (var tuple in methodSet)
|
||||
{
|
||||
if (tuple.Item3 != null && tuple.Item3.IsDisposed)
|
||||
{
|
||||
outOfSocpe.Add(tuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
var _result = tuple.Item2(__instance, args);
|
||||
if (_result != null)
|
||||
{
|
||||
if (_result is DynValue res)
|
||||
{
|
||||
if (!res.IsNil())
|
||||
{
|
||||
if (__originalMethod is MethodInfo mi && mi.ReturnType != typeof(void))
|
||||
{
|
||||
result = res.ToObject(mi.ReturnType);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = res.ToObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var tuple in outOfSocpe) { methodSet.Remove(tuple); }
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GameMain.LuaCs.PrintError($"Error in {__originalMethod.Name}:", LuaCsMessageOrigin.Unknown);
|
||||
GameMain.LuaCs.HandleException(ex, LuaCsMessageOrigin.Unknown);
|
||||
}
|
||||
}
|
||||
var outOfSocpe = new HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>();
|
||||
foreach (var tuple in methodSet)
|
||||
{
|
||||
if (tuple.Item3 != null && tuple.Item3.IsDisposed)
|
||||
{
|
||||
outOfSocpe.Add(tuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
var _result = tuple.Item2(__instance, args);
|
||||
if (_result != null)
|
||||
{
|
||||
if (_result is DynValue res)
|
||||
{
|
||||
if (!res.IsNil())
|
||||
{
|
||||
if (__originalMethod is MethodInfo mi && mi.ReturnType != typeof(void))
|
||||
{
|
||||
result = res.ToObject(mi.ReturnType);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = res.ToObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var tuple in outOfSocpe) { methodSet.Remove(tuple); }
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GameMain.LuaCs.PrintError($"Error in {__originalMethod.Name}:", LuaCsMessageOrigin.Unknown);
|
||||
GameMain.LuaCs.HandleException(ex, LuaCsMessageOrigin.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool HookLuaCsPatchPrefix(MethodBase __originalMethod, object[] __args, object __instance)
|
||||
{
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.Before);
|
||||
return result == null;
|
||||
}
|
||||
private static bool HookLuaCsPatchPrefix(MethodBase __originalMethod, object[] __args, object __instance)
|
||||
{
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.Before);
|
||||
return result == null;
|
||||
}
|
||||
|
||||
private static void HookLuaCsPatchPostfix(MethodBase __originalMethod, object[] __args, object __instance) =>
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object _, HookMethodType.After);
|
||||
private static void HookLuaCsPatchPostfix(MethodBase __originalMethod, object[] __args, object __instance) =>
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object _, HookMethodType.After);
|
||||
|
||||
private static bool HookLuaCsPatchRetPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance)
|
||||
{
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.Before);
|
||||
if (result != null)
|
||||
{
|
||||
__result = result;
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
private static bool HookLuaCsPatchRetPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance)
|
||||
{
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.Before);
|
||||
if (result != null)
|
||||
{
|
||||
__result = result;
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
private static void HookLuaCsPatchRetPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance)
|
||||
{
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.After);
|
||||
if (result != null) __result = result;
|
||||
}
|
||||
private static void HookLuaCsPatchRetPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance)
|
||||
{
|
||||
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.After);
|
||||
if (result != null) __result = result;
|
||||
}
|
||||
|
||||
private static MethodInfo _miHookLuaCsPatchPrefix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchPostfix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchRetPrefix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchRetPostfix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchRetPostfix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchPrefix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchPostfix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchRetPrefix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
private static MethodInfo _miHookLuaCsPatchRetPostfix = typeof(LuaCsHook).GetMethod("HookLuaCsPatchRetPostfix", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
// TODO: deprecate this
|
||||
public void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, HookMethodType hookType = HookMethodType.Before, ACsMod owner = null)
|
||||
{
|
||||
if (identifier == null || method == null || patch == null)
|
||||
{
|
||||
luaCs.HandleException(new ArgumentNullException("Identifier, Method and Patch arguments must not be null."), LuaCsMessageOrigin.Unknown);
|
||||
return;
|
||||
}
|
||||
ValidatePatchTarget(method);
|
||||
|
||||
var funcAddr = ((long)method.MethodHandle.GetFunctionPointer());
|
||||
var patches = Harmony.GetPatchInfo(method);
|
||||
|
||||
if (hookType == HookMethodType.Before)
|
||||
{
|
||||
if (method is MethodInfo mi && mi.ReturnType != typeof(void))
|
||||
{
|
||||
if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPrefix) == null)
|
||||
{
|
||||
harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchRetPrefix));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchPrefix) == null)
|
||||
{
|
||||
harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchPrefix));
|
||||
}
|
||||
}
|
||||
|
||||
if (compatHookPrefixMethods.TryGetValue(funcAddr, out HashSet<(string, LuaCsCompatPatchFunc, ACsMod)> methodSet))
|
||||
{
|
||||
if (identifier != "")
|
||||
{
|
||||
methodSet.RemoveWhere(tuple => tuple.Item1 == identifier);
|
||||
}
|
||||
|
||||
methodSet.Add((identifier, patch, owner));
|
||||
}
|
||||
else if (patch != null)
|
||||
{
|
||||
compatHookPrefixMethods.Add(funcAddr, new HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>() { (identifier, patch, owner) });
|
||||
}
|
||||
|
||||
}
|
||||
else if (hookType == HookMethodType.After)
|
||||
{
|
||||
if (method is MethodInfo mi && mi.ReturnType != typeof(void))
|
||||
{
|
||||
if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPostfix) == null)
|
||||
{
|
||||
harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchRetPostfix));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchPostfix) == null)
|
||||
{
|
||||
harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchPostfix));
|
||||
}
|
||||
}
|
||||
|
||||
if (compatHookPostfixMethods.TryGetValue(funcAddr, out HashSet<(string, LuaCsCompatPatchFunc, ACsMod)> methodSet))
|
||||
{
|
||||
if (identifier != "")
|
||||
{
|
||||
methodSet.RemoveWhere(tuple => tuple.Item1 == identifier);
|
||||
}
|
||||
|
||||
methodSet.Add((identifier, patch, owner));
|
||||
}
|
||||
else if (patch != null)
|
||||
{
|
||||
compatHookPostfixMethods.Add(funcAddr, new HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>() { (identifier, patch, owner) });
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void HookMethod(string identifier, string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before)
|
||||
{
|
||||
var method = ResolveMethod(className, methodName, parameterNames);
|
||||
if (method == null) return;
|
||||
if (method.GetParameters().Any(x => x.ParameterType.IsByRef))
|
||||
public void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, HookMethodType hookType = HookMethodType.Before, ACsMod owner = null)
|
||||
{
|
||||
if (identifier == null || method == null || patch == null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(HookMethod)} doesn't support ByRef parameters; use {nameof(Patch)} instead.");
|
||||
luaCs.HandleException(new ArgumentNullException("Identifier, Method and Patch arguments must not be null."), LuaCsMessageOrigin.Unknown);
|
||||
return;
|
||||
}
|
||||
HookMethod(identifier, method, patch, hookMethodType);
|
||||
}
|
||||
protected void HookMethod(string identifier, string className, string methodName, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) =>
|
||||
HookMethod(identifier, className, methodName, null, patch, hookMethodType);
|
||||
protected void HookMethod(string className, string methodName, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) =>
|
||||
HookMethod("", className, methodName, null, patch, hookMethodType);
|
||||
protected void HookMethod(string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) =>
|
||||
HookMethod("", className, methodName, parameterNames, patch, hookMethodType);
|
||||
ValidatePatchTarget(method);
|
||||
|
||||
var funcAddr = ((long)method.MethodHandle.GetFunctionPointer());
|
||||
var patches = Harmony.GetPatchInfo(method);
|
||||
|
||||
if (hookType == HookMethodType.Before)
|
||||
{
|
||||
if (method is MethodInfo mi && mi.ReturnType != typeof(void))
|
||||
{
|
||||
if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPrefix) == null)
|
||||
{
|
||||
harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchRetPrefix));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (patches == null || patches.Prefixes == null || patches.Prefixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchPrefix) == null)
|
||||
{
|
||||
harmony.Patch(method, prefix: new HarmonyMethod(_miHookLuaCsPatchPrefix));
|
||||
}
|
||||
}
|
||||
|
||||
if (compatHookPrefixMethods.TryGetValue(funcAddr, out HashSet<(string, LuaCsCompatPatchFunc, ACsMod)> methodSet))
|
||||
{
|
||||
if (identifier != "")
|
||||
{
|
||||
methodSet.RemoveWhere(tuple => tuple.Item1 == identifier);
|
||||
}
|
||||
|
||||
methodSet.Add((identifier, patch, owner));
|
||||
}
|
||||
else if (patch != null)
|
||||
{
|
||||
compatHookPrefixMethods.Add(funcAddr, new HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>() { (identifier, patch, owner) });
|
||||
}
|
||||
|
||||
}
|
||||
else if (hookType == HookMethodType.After)
|
||||
{
|
||||
if (method is MethodInfo mi && mi.ReturnType != typeof(void))
|
||||
{
|
||||
if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchRetPostfix) == null)
|
||||
{
|
||||
harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchRetPostfix));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (patches == null || patches.Postfixes == null || patches.Postfixes.Find(patch => patch.PatchMethod == _miHookLuaCsPatchPostfix) == null)
|
||||
{
|
||||
harmony.Patch(method, postfix: new HarmonyMethod(_miHookLuaCsPatchPostfix));
|
||||
}
|
||||
}
|
||||
|
||||
if (compatHookPostfixMethods.TryGetValue(funcAddr, out HashSet<(string, LuaCsCompatPatchFunc, ACsMod)> methodSet))
|
||||
{
|
||||
if (identifier != "")
|
||||
{
|
||||
methodSet.RemoveWhere(tuple => tuple.Item1 == identifier);
|
||||
}
|
||||
|
||||
methodSet.Add((identifier, patch, owner));
|
||||
}
|
||||
else if (patch != null)
|
||||
{
|
||||
compatHookPostfixMethods.Add(funcAddr, new HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>() { (identifier, patch, owner) });
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void HookMethod(string identifier, string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before)
|
||||
{
|
||||
var method = ResolveMethod(className, methodName, parameterNames);
|
||||
if (method == null) return;
|
||||
if (method.GetParameters().Any(x => x.ParameterType.IsByRef))
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(HookMethod)} doesn't support ByRef parameters; use {nameof(Patch)} instead.");
|
||||
}
|
||||
HookMethod(identifier, method, patch, hookMethodType);
|
||||
}
|
||||
protected void HookMethod(string identifier, string className, string methodName, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) =>
|
||||
HookMethod(identifier, className, methodName, null, patch, hookMethodType);
|
||||
protected void HookMethod(string className, string methodName, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) =>
|
||||
HookMethod("", className, methodName, null, patch, hookMethodType);
|
||||
protected void HookMethod(string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) =>
|
||||
HookMethod("", className, methodName, parameterNames, patch, hookMethodType);
|
||||
|
||||
|
||||
public void UnhookMethod(string identifier, MethodBase method, HookMethodType hookType = HookMethodType.Before)
|
||||
{
|
||||
var funcAddr = (long)method.MethodHandle.GetFunctionPointer();
|
||||
public void UnhookMethod(string identifier, MethodBase method, HookMethodType hookType = HookMethodType.Before)
|
||||
{
|
||||
var funcAddr = (long)method.MethodHandle.GetFunctionPointer();
|
||||
|
||||
Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>> methods;
|
||||
if (hookType == HookMethodType.Before) methods = compatHookPrefixMethods;
|
||||
else if (hookType == HookMethodType.After) methods = compatHookPostfixMethods;
|
||||
else throw null;
|
||||
Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, ACsMod)>> methods;
|
||||
if (hookType == HookMethodType.Before) methods = compatHookPrefixMethods;
|
||||
else if (hookType == HookMethodType.After) methods = compatHookPostfixMethods;
|
||||
else throw null;
|
||||
|
||||
if (methods.ContainsKey(funcAddr)) methods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier);
|
||||
}
|
||||
protected void UnhookMethod(string identifier, string className, string methodName, string[] parameterNames, HookMethodType hookType = HookMethodType.Before)
|
||||
{
|
||||
var method = ResolveMethod(className, methodName, parameterNames);
|
||||
if (method == null) return;
|
||||
UnhookMethod(identifier, method, hookType);
|
||||
}
|
||||
}
|
||||
if (methods.ContainsKey(funcAddr)) methods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier);
|
||||
}
|
||||
protected void UnhookMethod(string identifier, string className, string methodName, string[] parameterNames, HookMethodType hookType = HookMethodType.Before)
|
||||
{
|
||||
var method = ResolveMethod(className, methodName, parameterNames);
|
||||
if (method == null) return;
|
||||
UnhookMethod(identifier, method, hookType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,286 +11,286 @@ using MoonSharp.Interpreter;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaCsNetworking
|
||||
{
|
||||
public class HttpListener
|
||||
partial class LuaCsNetworking
|
||||
{
|
||||
public class HttpListener
|
||||
{
|
||||
private System.Net.HttpListener listener;
|
||||
private System.Net.HttpListener listener;
|
||||
|
||||
public HttpListener(System.Net.HttpListener list)
|
||||
{
|
||||
listener = list;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
listener.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public class IncomingHttpRequest
|
||||
{
|
||||
private HttpListenerRequest request;
|
||||
|
||||
public IncomingHttpRequest(HttpListenerRequest req)
|
||||
public HttpListener(System.Net.HttpListener list)
|
||||
{
|
||||
request = req;
|
||||
}
|
||||
listener = list;
|
||||
}
|
||||
|
||||
public string ContentType => request.ContentType;
|
||||
public string LocalEndPoint => request.LocalEndPoint.ToString();
|
||||
public string RemoteEndPoint => request.RemoteEndPoint.ToString();
|
||||
public string RawUrl => request.RawUrl;
|
||||
public Uri Url => request.Url;
|
||||
public string UserAgent => request.UserAgent;
|
||||
public string UserHostName => request.UserHostName;
|
||||
public string UserHostAddress => request.UserHostAddress;
|
||||
public NameValueCollection Headers => request.Headers;
|
||||
public string HttpMethod => request.HttpMethod;
|
||||
}
|
||||
public void Close()
|
||||
{
|
||||
listener.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public class IncomingHttpResponse
|
||||
{
|
||||
private HttpListenerResponse response;
|
||||
public class IncomingHttpRequest
|
||||
{
|
||||
private HttpListenerRequest request;
|
||||
|
||||
public IncomingHttpResponse(HttpListenerResponse resp)
|
||||
{
|
||||
response = resp;
|
||||
public IncomingHttpRequest(HttpListenerRequest req)
|
||||
{
|
||||
request = req;
|
||||
}
|
||||
|
||||
response.ContentType = "text/html";
|
||||
}
|
||||
public string ContentType => request.ContentType;
|
||||
public string LocalEndPoint => request.LocalEndPoint.ToString();
|
||||
public string RemoteEndPoint => request.RemoteEndPoint.ToString();
|
||||
public string RawUrl => request.RawUrl;
|
||||
public Uri Url => request.Url;
|
||||
public string UserAgent => request.UserAgent;
|
||||
public string UserHostName => request.UserHostName;
|
||||
public string UserHostAddress => request.UserHostAddress;
|
||||
public NameValueCollection Headers => request.Headers;
|
||||
public string HttpMethod => request.HttpMethod;
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
public class IncomingHttpResponse
|
||||
{
|
||||
private HttpListenerResponse response;
|
||||
|
||||
public IncomingHttpResponse(HttpListenerResponse resp)
|
||||
{
|
||||
response = resp;
|
||||
|
||||
response.ContentType = "text/html";
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return response.ContentType; }
|
||||
set { response.ContentType = value; }
|
||||
set { response.ContentType = value; }
|
||||
}
|
||||
|
||||
public void Write(string text)
|
||||
{
|
||||
byte[] data = Encoding.UTF8.GetBytes(text);
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
response.ContentLength64 = data.LongLength;
|
||||
public void Write(string text)
|
||||
{
|
||||
byte[] data = Encoding.UTF8.GetBytes(text);
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
response.ContentLength64 = data.LongLength;
|
||||
|
||||
response.OutputStream.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
response.OutputStream.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool RestrictMessageSize = true;
|
||||
public Dictionary<string, LuaCsAction> LuaCsNetReceives = new Dictionary<string, LuaCsAction>();
|
||||
public bool RestrictMessageSize = true;
|
||||
public Dictionary<string, LuaCsAction> LuaCsNetReceives = new Dictionary<string, LuaCsAction>();
|
||||
|
||||
#if SERVER
|
||||
[MoonSharpHidden]
|
||||
public void NetMessageReceived(IReadMessage netMessage, ClientPacketHeader header, Client client = null)
|
||||
{
|
||||
if (header == ClientPacketHeader.LUA_NET_MESSAGE)
|
||||
{
|
||||
string netMessageName = netMessage.ReadString();
|
||||
if (LuaCsNetReceives.ContainsKey(netMessageName))
|
||||
{
|
||||
try
|
||||
{
|
||||
LuaCsNetReceives[netMessageName](netMessage, client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO: make LuaCsNetworking hold a reference to LuaCsSetup instead of using this global
|
||||
GameMain.LuaCs.PrintError($"Exception thrown inside NetMessageReceive({netMessageName})", LuaCsMessageOrigin.Unknown);
|
||||
GameMain.LuaCs.HandleException(e, LuaCsMessageOrigin.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.LuaCs.Hook.Call("netMessageReceived", netMessage, header, client);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
[MoonSharpHidden]
|
||||
public void NetMessageReceived(IReadMessage netMessage, ServerPacketHeader header, Client client = null)
|
||||
{
|
||||
if (header == ServerPacketHeader.LUA_NET_MESSAGE)
|
||||
{
|
||||
string netMessageName = netMessage.ReadString();
|
||||
if (LuaCsNetReceives.ContainsKey(netMessageName))
|
||||
{
|
||||
try
|
||||
{
|
||||
LuaCsNetReceives[netMessageName](netMessage, client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.LuaCs.PrintError($"Exception thrown inside NetMessageReceive({netMessageName})", LuaCsMessageOrigin.Unknown);
|
||||
GameMain.LuaCs.HandleException(e, LuaCsMessageOrigin.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.LuaCs.Hook.Call("netMessageReceived", netMessage, header, client);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
public void Receive(string netMessageName, LuaCsAction callback)
|
||||
{
|
||||
LuaCsNetReceives[netMessageName] = callback;
|
||||
}
|
||||
|
||||
public IWriteMessage Start(string netMessageName)
|
||||
{
|
||||
var message = new WriteOnlyMessage();
|
||||
#if SERVER
|
||||
message.WriteByte((byte)ServerPacketHeader.LUA_NET_MESSAGE);
|
||||
#else
|
||||
message.WriteByte((byte)ClientPacketHeader.LUA_NET_MESSAGE);
|
||||
#endif
|
||||
message.WriteString(netMessageName);
|
||||
return message;
|
||||
}
|
||||
|
||||
public IWriteMessage Start()
|
||||
{
|
||||
return new WriteOnlyMessage();
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
public void ClientWriteLobby(Client client) => GameMain.Server.ClientWriteLobby(client);
|
||||
|
||||
public void Send(IWriteMessage netMessage, NetworkConnection connection = null, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable)
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
foreach (NetworkConnection conn in Client.ClientList.Select(c => c.Connection))
|
||||
{
|
||||
GameMain.Server.ServerPeer.Send(netMessage, conn, deliveryMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Server.ServerPeer.Send(netMessage, connection, deliveryMethod);
|
||||
}
|
||||
}
|
||||
#else
|
||||
public void Send(IWriteMessage netMessage, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable)
|
||||
{
|
||||
GameMain.Client.ClientPeer.Send(netMessage, deliveryMethod);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void HttpRequest(string url, LuaCsAction callback, string data = null, string method = "POST", string contentType = "application/json")
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
|
||||
httpWebRequest.ContentType = contentType;
|
||||
httpWebRequest.Method = method;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
||||
streamWriter.Write(data);
|
||||
}
|
||||
|
||||
httpWebRequest.BeginGetResponse(new AsyncCallback((IAsyncResult result) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpResponse = httpWebRequest.EndGetResponse(result);
|
||||
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
|
||||
{
|
||||
string responseResult = streamReader.ReadToEnd();
|
||||
GameMain.LuaCs.Timer.Wait((object[] par) => { callback(responseResult); }, 0);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.LuaCs.Timer.Wait((object[] par) => { callback(e.Message); }, 0);
|
||||
}
|
||||
}), null);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.LuaCs.Timer.Wait((object[] par) => { callback(e.Message); }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void HttpPost(string url, LuaCsAction callback, string data, string contentType = "application/json")
|
||||
[MoonSharpHidden]
|
||||
public void NetMessageReceived(IReadMessage netMessage, ClientPacketHeader header, Client client = null)
|
||||
{
|
||||
HttpRequest(url, callback, data, "POST", contentType);
|
||||
}
|
||||
if (header == ClientPacketHeader.LUA_NET_MESSAGE)
|
||||
{
|
||||
string netMessageName = netMessage.ReadString();
|
||||
if (LuaCsNetReceives.ContainsKey(netMessageName))
|
||||
{
|
||||
try
|
||||
{
|
||||
LuaCsNetReceives[netMessageName](netMessage, client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO: make LuaCsNetworking hold a reference to LuaCsSetup instead of using this global
|
||||
GameMain.LuaCs.PrintError($"Exception thrown inside NetMessageReceive({netMessageName})", LuaCsMessageOrigin.Unknown);
|
||||
GameMain.LuaCs.HandleException(e, LuaCsMessageOrigin.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.LuaCs.Hook.Call("netMessageReceived", netMessage, header, client);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
[MoonSharpHidden]
|
||||
public void NetMessageReceived(IReadMessage netMessage, ServerPacketHeader header, Client client = null)
|
||||
{
|
||||
if (header == ServerPacketHeader.LUA_NET_MESSAGE)
|
||||
{
|
||||
string netMessageName = netMessage.ReadString();
|
||||
if (LuaCsNetReceives.ContainsKey(netMessageName))
|
||||
{
|
||||
try
|
||||
{
|
||||
LuaCsNetReceives[netMessageName](netMessage, client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.LuaCs.PrintError($"Exception thrown inside NetMessageReceive({netMessageName})", LuaCsMessageOrigin.Unknown);
|
||||
GameMain.LuaCs.HandleException(e, LuaCsMessageOrigin.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.LuaCs.Hook.Call("netMessageReceived", netMessage, header, client);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
public void Receive(string netMessageName, LuaCsAction callback)
|
||||
{
|
||||
LuaCsNetReceives[netMessageName] = callback;
|
||||
}
|
||||
|
||||
public IWriteMessage Start(string netMessageName)
|
||||
{
|
||||
var message = new WriteOnlyMessage();
|
||||
#if SERVER
|
||||
message.WriteByte((byte)ServerPacketHeader.LUA_NET_MESSAGE);
|
||||
#else
|
||||
message.WriteByte((byte)ClientPacketHeader.LUA_NET_MESSAGE);
|
||||
#endif
|
||||
message.WriteString(netMessageName);
|
||||
return message;
|
||||
}
|
||||
|
||||
public IWriteMessage Start()
|
||||
{
|
||||
return new WriteOnlyMessage();
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
public void ClientWriteLobby(Client client) => GameMain.Server.ClientWriteLobby(client);
|
||||
|
||||
public void Send(IWriteMessage netMessage, NetworkConnection connection = null, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable)
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
foreach (NetworkConnection conn in Client.ClientList.Select(c => c.Connection))
|
||||
{
|
||||
GameMain.Server.ServerPeer.Send(netMessage, conn, deliveryMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Server.ServerPeer.Send(netMessage, connection, deliveryMethod);
|
||||
}
|
||||
}
|
||||
#else
|
||||
public void Send(IWriteMessage netMessage, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable)
|
||||
{
|
||||
GameMain.Client.ClientPeer.Send(netMessage, deliveryMethod);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void HttpRequest(string url, LuaCsAction callback, string data = null, string method = "POST", string contentType = "application/json")
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
|
||||
httpWebRequest.ContentType = contentType;
|
||||
httpWebRequest.Method = method;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
||||
streamWriter.Write(data);
|
||||
}
|
||||
|
||||
httpWebRequest.BeginGetResponse(new AsyncCallback((IAsyncResult result) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpResponse = httpWebRequest.EndGetResponse(result);
|
||||
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
|
||||
{
|
||||
string responseResult = streamReader.ReadToEnd();
|
||||
GameMain.LuaCs.Timer.Wait((object[] par) => { callback(responseResult); }, 0);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.LuaCs.Timer.Wait((object[] par) => { callback(e.Message); }, 0);
|
||||
}
|
||||
}), null);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.LuaCs.Timer.Wait((object[] par) => { callback(e.Message); }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void HttpPost(string url, LuaCsAction callback, string data, string contentType = "application/json")
|
||||
{
|
||||
HttpRequest(url, callback, data, "POST", contentType);
|
||||
}
|
||||
|
||||
|
||||
public void HttpGet(string url, LuaCsAction callback)
|
||||
{
|
||||
HttpRequest(url, callback, null, "GET");
|
||||
}
|
||||
public void HttpGet(string url, LuaCsAction callback)
|
||||
{
|
||||
HttpRequest(url, callback, null, "GET");
|
||||
}
|
||||
|
||||
public static async void HandleIncomingConnections(System.Net.HttpListener listener, LuaCsAction onRequestReceived)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (listener.IsListening)
|
||||
{
|
||||
HttpListenerContext ctx = await listener.GetContextAsync();
|
||||
public static async void HandleIncomingConnections(System.Net.HttpListener listener, LuaCsAction onRequestReceived)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (listener.IsListening)
|
||||
{
|
||||
HttpListenerContext ctx = await listener.GetContextAsync();
|
||||
|
||||
IncomingHttpRequest req = new IncomingHttpRequest(ctx.Request);
|
||||
IncomingHttpResponse resp = new IncomingHttpResponse(ctx.Response);
|
||||
IncomingHttpRequest req = new IncomingHttpRequest(ctx.Request);
|
||||
IncomingHttpResponse resp = new IncomingHttpResponse(ctx.Response);
|
||||
|
||||
onRequestReceived(req, resp);
|
||||
onRequestReceived(req, resp);
|
||||
|
||||
ctx.Response.Close();
|
||||
}
|
||||
ctx.Response.Close();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public LuaCsNetworking.HttpListener StartHttpServer(string address, LuaCsAction onRequestReceived)
|
||||
{
|
||||
var listener = new System.Net.HttpListener();
|
||||
listener.Prefixes.Add(address);
|
||||
listener.Start();
|
||||
var listener = new System.Net.HttpListener();
|
||||
listener.Prefixes.Add(address);
|
||||
listener.Start();
|
||||
|
||||
HandleIncomingConnections(listener, onRequestReceived);
|
||||
HandleIncomingConnections(listener, onRequestReceived);
|
||||
|
||||
return new LuaCsNetworking.HttpListener(listener);
|
||||
}
|
||||
return new LuaCsNetworking.HttpListener(listener);
|
||||
}
|
||||
|
||||
public void CreateEntityEvent(INetSerializable entity, NetEntityEvent.IData extraData)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(entity, extraData);
|
||||
}
|
||||
public void CreateEntityEvent(INetSerializable entity, NetEntityEvent.IData extraData)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(entity, extraData);
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
public void UpdateClientPermissions(Client client)
|
||||
{
|
||||
GameMain.Server.UpdateClientPermissions(client);
|
||||
}
|
||||
public void UpdateClientPermissions(Client client)
|
||||
{
|
||||
GameMain.Server.UpdateClientPermissions(client);
|
||||
}
|
||||
|
||||
public void RemovePendingClient(ServerPeer.PendingClient pendingClient, PeerDisconnectPacket peerDisconnectPacket)
|
||||
{
|
||||
GameMain.Server.ServerPeer.RemovePendingClient(pendingClient, peerDisconnectPacket);
|
||||
}
|
||||
public void RemovePendingClient(ServerPeer.PendingClient pendingClient, PeerDisconnectPacket peerDisconnectPacket)
|
||||
{
|
||||
GameMain.Server.ServerPeer.RemovePendingClient(pendingClient, peerDisconnectPacket);
|
||||
}
|
||||
|
||||
public int FileSenderMaxPacketsPerUpdate
|
||||
{
|
||||
get { return FileSender.FileTransferOut.MaxPacketsPerUpdate; }
|
||||
set { FileSender.FileTransferOut.MaxPacketsPerUpdate = value; }
|
||||
}
|
||||
public int FileSenderMaxPacketsPerUpdate
|
||||
{
|
||||
get { return FileSender.FileTransferOut.MaxPacketsPerUpdate; }
|
||||
set { FileSender.FileTransferOut.MaxPacketsPerUpdate = value; }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public ushort LastClientListUpdateID
|
||||
{
|
||||
get { return GameMain.NetworkMember.LastClientListUpdateID; }
|
||||
set { GameMain.NetworkMember.LastClientListUpdateID = value; }
|
||||
}
|
||||
}
|
||||
public ushort LastClientListUpdateID
|
||||
{
|
||||
get { return GameMain.NetworkMember.LastClientListUpdateID; }
|
||||
set { GameMain.NetworkMember.LastClientListUpdateID = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Steamworks;
|
||||
using Steamworks;
|
||||
using Steamworks.Data;
|
||||
using Barotrauma.Steam;
|
||||
using System.Threading;
|
||||
@@ -10,8 +10,8 @@ using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaCsSteam
|
||||
{
|
||||
partial class LuaCsSteam
|
||||
{
|
||||
private struct WorkshopItemDownload
|
||||
{
|
||||
public ulong ID;
|
||||
@@ -54,7 +54,7 @@ namespace Barotrauma
|
||||
{
|
||||
itemsBeingDownloaded.Add(download);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void DownloadWorkshopItem(ulong id, string destination, LuaCsAction callback)
|
||||
@@ -93,4 +93,4 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,47 +13,47 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaCsFile
|
||||
{
|
||||
public static bool CanReadFromPath(string path)
|
||||
{
|
||||
string getFullPath(string p) => System.IO.Path.GetFullPath(p).CleanUpPath();
|
||||
partial class LuaCsFile
|
||||
{
|
||||
public static bool CanReadFromPath(string path)
|
||||
{
|
||||
string getFullPath(string p) => System.IO.Path.GetFullPath(p).CleanUpPath();
|
||||
|
||||
path = getFullPath(path);
|
||||
path = getFullPath(path);
|
||||
|
||||
bool pathStartsWith(string prefix) => path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
|
||||
bool pathStartsWith(string prefix) => path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
string localModsDir = getFullPath(ContentPackage.LocalModsDir);
|
||||
string workshopModsDir = getFullPath(ContentPackage.WorkshopModsDir);
|
||||
string localModsDir = getFullPath(ContentPackage.LocalModsDir);
|
||||
string workshopModsDir = getFullPath(ContentPackage.WorkshopModsDir);
|
||||
#if CLIENT
|
||||
string tempDownloadDir = getFullPath(ModReceiver.DownloadFolder);
|
||||
#endif
|
||||
|
||||
|
||||
if (pathStartsWith(localModsDir))
|
||||
return true;
|
||||
if (pathStartsWith(localModsDir))
|
||||
return true;
|
||||
|
||||
if (pathStartsWith(workshopModsDir))
|
||||
return true;
|
||||
if (pathStartsWith(workshopModsDir))
|
||||
return true;
|
||||
|
||||
#if CLIENT
|
||||
if (pathStartsWith(tempDownloadDir))
|
||||
return true;
|
||||
if (pathStartsWith(tempDownloadDir))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (pathStartsWith(getFullPath(".")))
|
||||
return true;
|
||||
if (pathStartsWith(getFullPath(".")))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CanWriteToPath(string path)
|
||||
{
|
||||
string getFullPath(string p) => System.IO.Path.GetFullPath(p).CleanUpPath();
|
||||
public static bool CanWriteToPath(string path)
|
||||
{
|
||||
string getFullPath(string p) => System.IO.Path.GetFullPath(p).CleanUpPath();
|
||||
|
||||
path = getFullPath(path);
|
||||
path = getFullPath(path);
|
||||
|
||||
bool pathStartsWith(string prefix) => path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
|
||||
bool pathStartsWith(string prefix) => path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var package in ContentPackageManager.AllPackages)
|
||||
{
|
||||
@@ -67,451 +67,451 @@ namespace Barotrauma
|
||||
return true;
|
||||
|
||||
if (pathStartsWith(getFullPath(ContentPackage.LocalModsDir)))
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (pathStartsWith(getFullPath(ContentPackage.WorkshopModsDir)))
|
||||
return true;
|
||||
if (pathStartsWith(getFullPath(ContentPackage.WorkshopModsDir)))
|
||||
return true;
|
||||
#if CLIENT
|
||||
if (pathStartsWith(getFullPath(ModReceiver.DownloadFolder)))
|
||||
return true;
|
||||
if (pathStartsWith(getFullPath(ModReceiver.DownloadFolder)))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsPathAllowedException(string path, bool write = true, LuaCsMessageOrigin origin = LuaCsMessageOrigin.Unknown)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
if (CanWriteToPath(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("File access to \"" + path + "\" not allowed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CanReadFromPath(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("File access to \"" + path + "\" not allowed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
public static bool IsPathAllowedException(string path, bool write = true, LuaCsMessageOrigin origin = LuaCsMessageOrigin.Unknown)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
if (CanWriteToPath(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("File access to \"" + path + "\" not allowed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CanReadFromPath(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("File access to \"" + path + "\" not allowed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsPathAllowedLuaException(string path, bool write = true) =>
|
||||
IsPathAllowedException(path, write, LuaCsMessageOrigin.LuaMod);
|
||||
public static bool IsPathAllowedCsException(string path, bool write = true) =>
|
||||
IsPathAllowedException(path, write, LuaCsMessageOrigin.CSharpMod);
|
||||
public static bool IsPathAllowedLuaException(string path, bool write = true) =>
|
||||
IsPathAllowedException(path, write, LuaCsMessageOrigin.LuaMod);
|
||||
public static bool IsPathAllowedCsException(string path, bool write = true) =>
|
||||
IsPathAllowedException(path, write, LuaCsMessageOrigin.CSharpMod);
|
||||
|
||||
public static string Read(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return "";
|
||||
public static string Read(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return "";
|
||||
|
||||
return File.ReadAllText(path);
|
||||
}
|
||||
return File.ReadAllText(path);
|
||||
}
|
||||
|
||||
public static void Write(string path, string text)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return;
|
||||
public static void Write(string path, string text)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return;
|
||||
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
|
||||
public static void Delete(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return;
|
||||
public static void Delete(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return;
|
||||
|
||||
File.Delete(path);
|
||||
}
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
public static void DeleteDirectory(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return;
|
||||
public static void DeleteDirectory(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return;
|
||||
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
|
||||
public static FileStream OpenRead(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return null;
|
||||
public static FileStream OpenRead(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return null;
|
||||
|
||||
return File.Open(path, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
public static FileStream OpenWrite(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return null;
|
||||
return File.Open(path, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
public static FileStream OpenWrite(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return null;
|
||||
|
||||
if (File.Exists(path)) return File.Open(path, FileMode.Truncate, FileAccess.Write);
|
||||
else return File.Open(path, FileMode.Create, FileAccess.Write);
|
||||
}
|
||||
if (File.Exists(path)) return File.Open(path, FileMode.Truncate, FileAccess.Write);
|
||||
else return File.Open(path, FileMode.Create, FileAccess.Write);
|
||||
}
|
||||
|
||||
public static bool Exists(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return false;
|
||||
public static bool Exists(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return false;
|
||||
|
||||
return File.Exists(path);
|
||||
}
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
||||
public static bool CreateDirectory(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return false;
|
||||
public static bool CreateDirectory(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path))
|
||||
return false;
|
||||
|
||||
Directory.CreateDirectory(path);
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool DirectoryExists(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return false;
|
||||
public static bool DirectoryExists(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return false;
|
||||
|
||||
return Directory.Exists(path);
|
||||
}
|
||||
return Directory.Exists(path);
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return null;
|
||||
public static string[] GetFiles(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return null;
|
||||
|
||||
return Directory.GetFiles(path);
|
||||
}
|
||||
return Directory.GetFiles(path);
|
||||
}
|
||||
|
||||
public static string[] GetDirectories(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return new string[] { };
|
||||
public static string[] GetDirectories(string path)
|
||||
{
|
||||
if (!IsPathAllowedException(path, false))
|
||||
return new string[] { };
|
||||
|
||||
return Directory.GetDirectories(path);
|
||||
}
|
||||
return Directory.GetDirectories(path);
|
||||
}
|
||||
|
||||
public static string[] DirSearch(string sDir)
|
||||
{
|
||||
if (!IsPathAllowedException(sDir, false))
|
||||
return new string[] { };
|
||||
public static string[] DirSearch(string sDir)
|
||||
{
|
||||
if (!IsPathAllowedException(sDir, false))
|
||||
return new string[] { };
|
||||
|
||||
List<string> files = new List<string>();
|
||||
List<string> files = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (string f in Directory.GetFiles(sDir))
|
||||
{
|
||||
files.Add(f);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
return files.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LuaCsConfig
|
||||
class LuaCsConfig
|
||||
{
|
||||
private enum ValueType
|
||||
private enum ValueType
|
||||
{
|
||||
None,
|
||||
Text,
|
||||
Integer,
|
||||
Decimal,
|
||||
Boolean,
|
||||
Collection,
|
||||
Object,
|
||||
Enum
|
||||
None,
|
||||
Text,
|
||||
Integer,
|
||||
Decimal,
|
||||
Boolean,
|
||||
Collection,
|
||||
Object,
|
||||
Enum
|
||||
}
|
||||
|
||||
private static Type[] LoadDocTypes(XElement typesElem)
|
||||
private static Type[] LoadDocTypes(XElement typesElem)
|
||||
{
|
||||
var result = new List<Type>();
|
||||
foreach (var elem in typesElem.Elements())
|
||||
var result = new List<Type>();
|
||||
foreach (var elem in typesElem.Elements())
|
||||
{
|
||||
var type = Type.GetType(elem.Value);
|
||||
if (type == null && GameMain.LuaCs?.CsScriptLoader?.Assembly != null) type = GameMain.LuaCs.CsScriptLoader.Assembly.GetType(elem.Value);
|
||||
if (type == null) throw new Exception($"Type {elem.Value} not found.");
|
||||
result.Add(type);
|
||||
var type = Type.GetType(elem.Value);
|
||||
if (type == null && GameMain.LuaCs?.CsScriptLoader?.Assembly != null) type = GameMain.LuaCs.CsScriptLoader.Assembly.GetType(elem.Value);
|
||||
if (type == null) throw new Exception($"Type {elem.Value} not found.");
|
||||
result.Add(type);
|
||||
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private static IEnumerable<XElement> SaveDocTypes(IEnumerable<Type> types)
|
||||
{
|
||||
return types.Select(t => new XElement("Type", t.ToString()));
|
||||
}
|
||||
|
||||
private static Type GetTypeAttr(Type[] types, XElement elem)
|
||||
private static IEnumerable<XElement> SaveDocTypes(IEnumerable<Type> types)
|
||||
{
|
||||
var idx = elem.GetAttributeInt("Type", -1);
|
||||
if (idx < 0 || idx >= types.Length) throw new Exception($"Type index '{idx}' is outside of saved types bounds");
|
||||
return types[idx];
|
||||
}
|
||||
private static ValueType GetValueType(XElement elem)
|
||||
return types.Select(t => new XElement("Type", t.ToString()));
|
||||
}
|
||||
|
||||
private static Type GetTypeAttr(Type[] types, XElement elem)
|
||||
{
|
||||
Enum.TryParse(typeof(ValueType), elem.Attribute("Value")?.Value, out object result);
|
||||
if (result != null) return (ValueType)result;
|
||||
else return ValueType.None;
|
||||
}
|
||||
private static object ParseValue(Type[] types, XElement elem)
|
||||
var idx = elem.GetAttributeInt("Type", -1);
|
||||
if (idx < 0 || idx >= types.Length) throw new Exception($"Type index '{idx}' is outside of saved types bounds");
|
||||
return types[idx];
|
||||
}
|
||||
private static ValueType GetValueType(XElement elem)
|
||||
{
|
||||
var type = GetValueType(elem);
|
||||
Enum.TryParse(typeof(ValueType), elem.Attribute("Value")?.Value, out object result);
|
||||
if (result != null) return (ValueType)result;
|
||||
else return ValueType.None;
|
||||
}
|
||||
private static object ParseValue(Type[] types, XElement elem)
|
||||
{
|
||||
var type = GetValueType(elem);
|
||||
|
||||
if (elem.IsEmpty) return null;
|
||||
if (type == ValueType.Enum)
|
||||
if (elem.IsEmpty) return null;
|
||||
if (type == ValueType.Enum)
|
||||
{
|
||||
var tType = GetTypeAttr(types, elem);
|
||||
if (tType == null || !tType.IsSubclassOf(typeof(Enum))) return null;
|
||||
if (Enum.TryParse(tType, elem.Value, out object result)) return result;
|
||||
else return null;
|
||||
}
|
||||
if (type == ValueType.Collection)
|
||||
{
|
||||
var tType = GetTypeAttr(types, elem);
|
||||
var tInt = tType.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
||||
var gArg = tInt.GetGenericArguments()[0];
|
||||
if (tType == null || !tType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))) return null;
|
||||
|
||||
object result = null;
|
||||
|
||||
if (result == null) {
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c =>
|
||||
{
|
||||
var param = c.GetParameters();
|
||||
return param.Count() == 1 && param.Any(p => p.ParameterType.IsGenericType && p.ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
||||
});
|
||||
if (ctor != null)
|
||||
{
|
||||
var elements = elem.Elements().Select(x => ParseValue(types, x));
|
||||
var castElems = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(gArg).Invoke(elements, new object[] { elements });
|
||||
result = ctor.Invoke(new object[] { castElems });
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c => c.GetParameters().Count() == 0);
|
||||
var addMethod = tType.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(m =>
|
||||
{
|
||||
if (m.Name != "Add") return false;
|
||||
var param = m.GetParameters();
|
||||
return param.Count() == 1 && param[0].ParameterType == gArg;
|
||||
});
|
||||
if (ctor != null && addMethod != null)
|
||||
{
|
||||
var elements = elem.Elements().Select(x => ParseValue(types, x));
|
||||
result = ctor.Invoke(null);
|
||||
foreach (var el in elements) addMethod.Invoke(result, new object[] { el });
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault();
|
||||
var setMethod = tType.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(m =>
|
||||
{
|
||||
if (m.Name != "Set") return false;
|
||||
var param = m.GetParameters();
|
||||
return param.Count() == 2 && param[0].ParameterType == typeof(int) && param[1].ParameterType == gArg;
|
||||
});
|
||||
if (ctor != null || setMethod != null)
|
||||
{
|
||||
var elements = elem.Elements().Select(x => ParseValue(types, x));
|
||||
result = ctor.Invoke(new object[] { elements.Count() });
|
||||
int i = 0;
|
||||
foreach (var el in elements)
|
||||
{
|
||||
setMethod.Invoke(result, new object[] { i, el });
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (type == ValueType.Text) return elem.Value;
|
||||
else if (type == ValueType.Integer)
|
||||
{
|
||||
int.TryParse(elem.Value, out var num);
|
||||
return num;
|
||||
}
|
||||
else if (type == ValueType.Decimal)
|
||||
var tType = GetTypeAttr(types, elem);
|
||||
if (tType == null || !tType.IsSubclassOf(typeof(Enum))) return null;
|
||||
if (Enum.TryParse(tType, elem.Value, out object result)) return result;
|
||||
else return null;
|
||||
}
|
||||
if (type == ValueType.Collection)
|
||||
{
|
||||
float.TryParse(elem.Value, out var num);
|
||||
return num;
|
||||
}
|
||||
else if (type == ValueType.Boolean)
|
||||
{
|
||||
bool.TryParse(elem.Value, out var boolean);
|
||||
return boolean;
|
||||
}
|
||||
else if (type == ValueType.Object)
|
||||
{
|
||||
var tType = GetTypeAttr(types, elem);
|
||||
if (tType == null) return null;
|
||||
var tType = GetTypeAttr(types, elem);
|
||||
var tInt = tType.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
||||
var gArg = tInt.GetGenericArguments()[0];
|
||||
if (tType == null || !tType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))) return null;
|
||||
|
||||
IEnumerable<FieldInfo> fields = tType.GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Concat(tType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic));
|
||||
IEnumerable<PropertyInfo> properties = tType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.GetSetMethod() != null)
|
||||
.Concat(tType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Where(p => p.GetSetMethod() != null));
|
||||
object result = null;
|
||||
|
||||
object result = null;
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c => c.GetParameters().Count() == 0);
|
||||
if (ctor == null)
|
||||
{
|
||||
if (!tType.IsValueType) return null;
|
||||
result = Activator.CreateInstance(tType);
|
||||
}
|
||||
else result = ctor.Invoke(null);
|
||||
|
||||
foreach(var el in elem.Elements())
|
||||
{
|
||||
var value = ParseValue(types, el);
|
||||
|
||||
var field = fields.FirstOrDefault(f => f.Name == el.Name.LocalName);
|
||||
if (field != null) field.SetValue(result, value);
|
||||
var property = properties.FirstOrDefault(p => p.Name == el.Name.LocalName);
|
||||
if (property != null) property.SetValue(result, value);
|
||||
if (result == null) {
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c =>
|
||||
{
|
||||
var param = c.GetParameters();
|
||||
return param.Count() == 1 && param.Any(p => p.ParameterType.IsGenericType && p.ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
||||
});
|
||||
if (ctor != null)
|
||||
{
|
||||
var elements = elem.Elements().Select(x => ParseValue(types, x));
|
||||
var castElems = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(gArg).Invoke(elements, new object[] { elements });
|
||||
result = ctor.Invoke(new object[] { castElems });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else return elem.Value;
|
||||
|
||||
}
|
||||
|
||||
private static void AddTypeAttr(List<Type> types, Type type, XElement elem)
|
||||
{
|
||||
if (!types.Contains(type)) types.Add(type);
|
||||
elem.SetAttributeValue("Type", types.IndexOf(type));
|
||||
}
|
||||
|
||||
private static XElement ParseObject(List<Type> types, string name, object value)
|
||||
{
|
||||
XElement result = new XElement(name);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
var tType = value.GetType();
|
||||
|
||||
if (tType.IsEnum)
|
||||
if (result == null)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Enum);
|
||||
AddTypeAttr(types, tType, result);
|
||||
|
||||
result.Value = Enum.GetName(tType, value) ?? "";
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c => c.GetParameters().Count() == 0);
|
||||
var addMethod = tType.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(m =>
|
||||
{
|
||||
if (m.Name != "Add") return false;
|
||||
var param = m.GetParameters();
|
||||
return param.Count() == 1 && param[0].ParameterType == gArg;
|
||||
});
|
||||
if (ctor != null && addMethod != null)
|
||||
{
|
||||
var elements = elem.Elements().Select(x => ParseValue(types, x));
|
||||
result = ctor.Invoke(null);
|
||||
foreach (var el in elements) addMethod.Invoke(result, new object[] { el });
|
||||
}
|
||||
}
|
||||
else if (value is string str)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Text);
|
||||
result.Value = str;
|
||||
}
|
||||
else if (value is int integer)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Integer);
|
||||
result.Value = integer.ToString();
|
||||
}
|
||||
else if (value is float || value is double)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Decimal);
|
||||
result.Value = value.ToString();
|
||||
}
|
||||
else if (value is bool boolean)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Boolean);
|
||||
result.Value = boolean.ToString();
|
||||
}
|
||||
else if (tType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Collection);
|
||||
AddTypeAttr(types, tType, result);
|
||||
|
||||
var enumerator = (IEnumerator)tType.GetMethod("GetEnumerator").Invoke(value, null);
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var elVal = ParseObject(types, "Item", enumerator.Current);
|
||||
result.Add(elVal);
|
||||
}
|
||||
}
|
||||
else if (tType.IsClass || tType.IsValueType)
|
||||
if (result == null)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Object);
|
||||
AddTypeAttr(types, tType, result);
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault();
|
||||
var setMethod = tType.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(m =>
|
||||
{
|
||||
if (m.Name != "Set") return false;
|
||||
var param = m.GetParameters();
|
||||
return param.Count() == 2 && param[0].ParameterType == typeof(int) && param[1].ParameterType == gArg;
|
||||
});
|
||||
if (ctor != null || setMethod != null)
|
||||
{
|
||||
var elements = elem.Elements().Select(x => ParseValue(types, x));
|
||||
result = ctor.Invoke(new object[] { elements.Count() });
|
||||
int i = 0;
|
||||
foreach (var el in elements)
|
||||
{
|
||||
setMethod.Invoke(result, new object[] { i, el });
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<FieldInfo> fields = tType.GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Concat(tType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic));
|
||||
IEnumerable<PropertyInfo> properties = tType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.GetSetMethod() != null)
|
||||
.Concat(tType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Where(p => p.GetSetMethod() != null));
|
||||
return result;
|
||||
}
|
||||
else if (type == ValueType.Text) return elem.Value;
|
||||
else if (type == ValueType.Integer)
|
||||
{
|
||||
int.TryParse(elem.Value, out var num);
|
||||
return num;
|
||||
}
|
||||
else if (type == ValueType.Decimal)
|
||||
{
|
||||
float.TryParse(elem.Value, out var num);
|
||||
return num;
|
||||
}
|
||||
else if (type == ValueType.Boolean)
|
||||
{
|
||||
bool.TryParse(elem.Value, out var boolean);
|
||||
return boolean;
|
||||
}
|
||||
else if (type == ValueType.Object)
|
||||
{
|
||||
var tType = GetTypeAttr(types, elem);
|
||||
if (tType == null) return null;
|
||||
|
||||
foreach(var field in fields) result.Add(ParseObject(types, field.Name, field.GetValue(value)));
|
||||
foreach (var property in properties) result.Add(ParseObject(types, property.Name, property.GetValue(value)));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.None);
|
||||
result.Value = value.ToString();
|
||||
}
|
||||
}
|
||||
IEnumerable<FieldInfo> fields = tType.GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Concat(tType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic));
|
||||
IEnumerable<PropertyInfo> properties = tType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.GetSetMethod() != null)
|
||||
.Concat(tType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Where(p => p.GetSetMethod() != null));
|
||||
|
||||
return result;
|
||||
object result = null;
|
||||
var ctor = tType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c => c.GetParameters().Count() == 0);
|
||||
if (ctor == null)
|
||||
{
|
||||
if (!tType.IsValueType) return null;
|
||||
result = Activator.CreateInstance(tType);
|
||||
}
|
||||
else result = ctor.Invoke(null);
|
||||
|
||||
foreach(var el in elem.Elements())
|
||||
{
|
||||
var value = ParseValue(types, el);
|
||||
|
||||
var field = fields.FirstOrDefault(f => f.Name == el.Name.LocalName);
|
||||
if (field != null) field.SetValue(result, value);
|
||||
var property = properties.FirstOrDefault(p => p.Name == el.Name.LocalName);
|
||||
if (property != null) property.SetValue(result, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else return elem.Value;
|
||||
|
||||
}
|
||||
|
||||
private static void AddTypeAttr(List<Type> types, Type type, XElement elem)
|
||||
{
|
||||
if (!types.Contains(type)) types.Add(type);
|
||||
elem.SetAttributeValue("Type", types.IndexOf(type));
|
||||
}
|
||||
|
||||
private static XElement ParseObject(List<Type> types, string name, object value)
|
||||
{
|
||||
XElement result = new XElement(name);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
var tType = value.GetType();
|
||||
|
||||
if (tType.IsEnum)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Enum);
|
||||
AddTypeAttr(types, tType, result);
|
||||
|
||||
result.Value = Enum.GetName(tType, value) ?? "";
|
||||
}
|
||||
else if (value is string str)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Text);
|
||||
result.Value = str;
|
||||
}
|
||||
else if (value is int integer)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Integer);
|
||||
result.Value = integer.ToString();
|
||||
}
|
||||
else if (value is float || value is double)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Decimal);
|
||||
result.Value = value.ToString();
|
||||
}
|
||||
else if (value is bool boolean)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Boolean);
|
||||
result.Value = boolean.ToString();
|
||||
}
|
||||
else if (tType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Collection);
|
||||
AddTypeAttr(types, tType, result);
|
||||
|
||||
var enumerator = (IEnumerator)tType.GetMethod("GetEnumerator").Invoke(value, null);
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var elVal = ParseObject(types, "Item", enumerator.Current);
|
||||
result.Add(elVal);
|
||||
}
|
||||
}
|
||||
else if (tType.IsClass || tType.IsValueType)
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.Object);
|
||||
AddTypeAttr(types, tType, result);
|
||||
|
||||
IEnumerable<FieldInfo> fields = tType.GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Concat(tType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic));
|
||||
IEnumerable<PropertyInfo> properties = tType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.GetSetMethod() != null)
|
||||
.Concat(tType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Where(p => p.GetSetMethod() != null));
|
||||
|
||||
foreach(var field in fields) result.Add(ParseObject(types, field.Name, field.GetValue(value)));
|
||||
foreach (var property in properties) result.Add(ParseObject(types, property.Name, property.GetValue(value)));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.SetAttributeValue("Value", ValueType.None);
|
||||
result.Value = value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static T Load<T>(FileStream file)
|
||||
{
|
||||
var doc = XDocument.Load(file);
|
||||
|
||||
var rootElems = doc.Root.Elements().ToArray();
|
||||
var types = rootElems[0];
|
||||
var elem = rootElems[1];
|
||||
|
||||
var dict = ParseValue(LoadDocTypes(types), elem);
|
||||
if (dict.GetType() == typeof(T)) return (T)dict;
|
||||
else throw new Exception($"Loaded configuration is not of the type '{typeof(T).Name}'");
|
||||
}
|
||||
|
||||
public static void Save(FileStream file, object obj)
|
||||
{
|
||||
var types = new List<Type>();
|
||||
var elem = ParseObject(types, "Root", obj);
|
||||
var root = new XElement("Configuration", new XElement("Types", SaveDocTypes(types)), elem);
|
||||
|
||||
var doc = new XDocument(root);
|
||||
doc.Save(file);
|
||||
}
|
||||
|
||||
public static T Load<T>(string path)
|
||||
{
|
||||
using (var file = LuaCsFile.OpenRead(path)) return Load<T>(file);
|
||||
}
|
||||
|
||||
public static void Save(string path, object obj)
|
||||
public static T Load<T>(FileStream file)
|
||||
{
|
||||
using (var file = LuaCsFile.OpenWrite(path)) Save(file, obj);
|
||||
}
|
||||
var doc = XDocument.Load(file);
|
||||
|
||||
var rootElems = doc.Root.Elements().ToArray();
|
||||
var types = rootElems[0];
|
||||
var elem = rootElems[1];
|
||||
|
||||
var dict = ParseValue(LoadDocTypes(types), elem);
|
||||
if (dict.GetType() == typeof(T)) return (T)dict;
|
||||
else throw new Exception($"Loaded configuration is not of the type '{typeof(T).Name}'");
|
||||
}
|
||||
|
||||
public static void Save(FileStream file, object obj)
|
||||
{
|
||||
var types = new List<Type>();
|
||||
var elem = ParseObject(types, "Root", obj);
|
||||
var root = new XElement("Configuration", new XElement("Types", SaveDocTypes(types)), elem);
|
||||
|
||||
var doc = new XDocument(root);
|
||||
doc.Save(file);
|
||||
}
|
||||
|
||||
public static T Load<T>(string path)
|
||||
{
|
||||
using (var file = LuaCsFile.OpenRead(path)) return Load<T>(file);
|
||||
}
|
||||
|
||||
public static void Save(string path, object obj)
|
||||
{
|
||||
using (var file = LuaCsFile.OpenWrite(path)) Save(file, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user