Semi-working Lua scripts

This commit is contained in:
Evil Factory
2026-01-25 20:26:14 -03:00
committed by Maplewheels
parent 295c365a8f
commit 3d51abc56b
12 changed files with 154 additions and 219 deletions
@@ -11,7 +11,7 @@ namespace Barotrauma
internal class LuaUserData
{
[Obsolete("Use IPluginManagementService::GetTypesByName()")]
public static Type GetType(string typeName) => throw new NotImplementedException(); //LuaCsSetup.GetType(typeName);
public static Type GetType(string typeName) => GameMain.LuaCs.PluginManagementService.GetType(typeName); //LuaCsSetup.GetType(typeName);
public static IUserDataDescriptor RegisterType(string typeName)
{
@@ -44,7 +44,7 @@ namespace Barotrauma
SubscribeToLuaCsEvents();
}
bool ValidateLuaCsContent()
private bool ValidateLuaCsContent()
{
#if DEBUG
// TODO: we just wanna boot for now
@@ -57,7 +57,7 @@ namespace Barotrauma
throw new NotImplementedException();
}
void SubscribeToLuaCsEvents()
private void SubscribeToLuaCsEvents()
{
EventService.Subscribe<IEventScreenSelected>(this); // game state hook in
EventService.Subscribe<IEventEnabledPackageListChanged>(this);
@@ -283,7 +283,13 @@ namespace Barotrauma
DisposeLuaCsConfig();
Logger.LogResults(PackageManagementService.UnloadAllPackages());
}
LuaScriptManagementService.Reset();
PackageManagementService.Reset();
EventService.Reset();
SubscribeToLuaCsEvents();
CurrentRunState = RunState.Unloaded;
}
@@ -348,6 +348,7 @@ public class EventService : IEventService, IEventAssemblyContextUnloading
_subscriptions.Clear();
_luaSubscriptionFactories.Clear();
_eventTypeNameAliases.Clear();
_luaLegacySubscriptionFactories.Clear();
GC.SuppressFinalize(this);
}
@@ -357,6 +358,7 @@ public class EventService : IEventService, IEventAssemblyContextUnloading
_subscriptions.Clear();
_luaSubscriptionFactories.Clear();
_eventTypeNameAliases.Clear();
_luaLegacySubscriptionFactories.Clear();
return FluentResults.Result.Ok();
}
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Barotrauma.Networking;
using FluentResults;
using Microsoft.Xna.Framework;
using MoonSharp.Interpreter;
@@ -132,6 +133,42 @@ public partial class LoggerService : ILoggerService
#endif
}
public void HandleException(Exception ex)
{
string errorString = "";
switch (ex)
{
case NetRuntimeException netRuntimeException:
if (netRuntimeException.DecoratedMessage == null)
{
errorString = netRuntimeException.ToString();
}
else
{
// FIXME: netRuntimeException.ToString() doesn't print the InnerException's stack trace...
errorString = $"{netRuntimeException.DecoratedMessage}: {netRuntimeException}";
}
break;
case InterpreterException interpreterException:
if (interpreterException.DecoratedMessage == null)
{
errorString = interpreterException.ToString();
}
else
{
errorString = interpreterException.DecoratedMessage;
}
break;
default:
errorString = ex.StackTrace != null
? ex.ToString()
: $"{ex}\n{Environment.StackTrace}";
break;
}
LogError(errorString);
}
public void LogResults(FluentResults.Result result)
{
if (result == null)
@@ -149,7 +186,15 @@ public partial class LoggerService : ILoggerService
{
foreach (var error in result.Errors)
{
LogError(error.Message);
if (error is ExceptionalError exceptionalError)
{
HandleException(exceptionalError.Exception);
}
else
{
LogError(error.Message);
}
if (error.Reasons != null)
{
@@ -7,10 +7,12 @@ using Barotrauma.Networking;
using FluentResults;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Toolkit.Diagnostics;
using MonoMod.RuntimeDetour;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
using MoonSharp.Interpreter.Loaders;
using RestSharp.Validation;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -18,12 +20,12 @@ using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Toolkit.Diagnostics;
using static Barotrauma.GameSettings;
namespace Barotrauma.LuaCs.Services;
@@ -97,6 +99,46 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
return new FluentResults.Result().WithReasons(cacheRes.Value.SelectMany(cr => cr.Item2.Reasons));
}
private DynValue DoFile(string file, Table? globalContext = null, string? codeStringFriendly = null)
{
if (_script == null)
{
throw new Exception("Not running");
}
if (!LuaCsFile.CanReadFromPath(file))
{
throw new ScriptRuntimeException($"dofile: File access to {file} not allowed.");
}
if (!LuaCsFile.Exists(file))
{
throw new ScriptRuntimeException($"dofile: File {file} not found.");
}
return _script.DoFile(file, globalContext, codeStringFriendly);
}
private DynValue LoadFile(string file, Table? globalContext = null, string? codeStringFriendly = null)
{
if (_script == null)
{
throw new Exception("Not running");
}
if (!LuaCsFile.CanReadFromPath(file))
{
throw new ScriptRuntimeException($"loadfile: File access to {file} not allowed.");
}
if (!LuaCsFile.Exists(file))
{
throw new ScriptRuntimeException($"loadfile: File {file} not found.");
}
return _script.LoadFile(file, globalContext, codeStringFriendly);
}
private void SetupEnvironment()
{
_script = new Script(CoreModules.Preset_SoftSandbox | CoreModules.Debug | CoreModules.IO | CoreModules.OS_System);
@@ -115,9 +157,21 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
RegisterType(typeof(ILuaCsUtility));
RegisterType(typeof(ILuaCsTimer));
RegisterType(typeof(LuaCsFile));
RegisterType(typeof(ILuaScriptResourceInfo));
RegisterType(typeof(IResourceInfo));
RegisterType(typeof(LuaUserData));
RegisterType(typeof(IUserDataDescriptor));
new LuaConverters(_script).RegisterLuaConverters();
var luaRequire = new LuaRequire(_script);
_script.Globals["setmodulepaths"] = (string[] str) => ((LuaScriptLoader)_luaScriptLoader).ModulePaths = str;
_script.Globals["dofile"] = (Func<string, Table, string, DynValue>)DoFile;
_script.Globals["loadfile"] = (Func<string, Table, string, DynValue>)LoadFile;
_script.Globals["require"] = (Func<string, Table, DynValue>)luaRequire.Require;
_script.Globals["printerror"] = (DynValue o) => { LuaCsLogger.LogError(o.ToString()); };
_script.Globals["dostring"] = (Func<string, Table, string, DynValue>)_script.DoString;
@@ -129,6 +183,7 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
_script.Globals["File"] = UserData.CreateStatic<LuaCsFile>();
//_script.Globals["Networking"] = _luaCsNetworking;
//_script.Globals["Steam"] = Steam;
_script.Globals["LuaUserData"] = UserData.CreateStatic<LuaUserData>();
_script.Globals["ExecutionNumber"] = 0;
_script.Globals["CSActive"] = false;
@@ -138,9 +193,7 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
}
public FluentResults.Result ExecuteLoadedScripts(ImmutableArray<ILuaScriptResourceInfo> executionOrder)
{
throw new NotImplementedException($"Need to implement {nameof(executionOrder)} logic.");
{
if (_isRunning)
{
return FluentResults.Result.Fail("Tried to execute Lua scripts without unloading first.");
@@ -152,13 +205,16 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
var result = FluentResults.Result.Ok();
foreach (ILuaScriptResourceInfo resource in _resourcesInfo)
List<ILuaScriptResourceInfo> initializationScripts = executionOrder.Where(x => x.OwnerPackage.Name == "LuaCsForBarotrauma").ToList();
List<ILuaScriptResourceInfo> otherScripts = executionOrder.Except(initializationScripts).ToList();
foreach (ILuaScriptResourceInfo resource in initializationScripts)
{
foreach (ContentPath filePath in resource.FilePaths)
{
try
{
_script?.Call(_script.LoadFile(filePath.FullPath));
_script?.Call(_script.LoadFile(filePath.FullPath), Path.GetDirectoryName(resource.OwnerPackage.Path), otherScripts.ToList());
}
catch(Exception e)
{
@@ -78,7 +78,7 @@ public class PluginManagementService : IPluginManagementService, IAssemblyManage
if (IsDisposed)
return FluentResults.Result.Fail($"{nameof(PluginManagementService)} is disposed!");
throw new NotImplementedException();
return FluentResults.Result.Fail("not implemented");
}
public Result<ImmutableArray<Type>> GetImplementingTypes<T>(bool includeInterfaces = false,
@@ -1,4 +1,11 @@
using System;
using Barotrauma.IO;
using Barotrauma.LuaCs.Data;
using Barotrauma.Networking;
using FarseerPhysics.Common;
using FluentResults;
using FluentResults.LuaCs;
using Microsoft.Toolkit.Diagnostics;
using System;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.IO;
@@ -6,12 +13,6 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Barotrauma.IO;
using Barotrauma.LuaCs.Data;
using FarseerPhysics.Common;
using FluentResults;
using FluentResults.LuaCs;
using Microsoft.Toolkit.Diagnostics;
using Path = System.IO.Path;
namespace Barotrauma.LuaCs.Services.Safe;
@@ -40,6 +41,17 @@ public class SafeStorageService : StorageService, ISafeStorageService
try
{
path = GetFullPath(path);
if (path.StartsWith(ConfigData.WorkshopModsDirectory)
|| path.StartsWith(ConfigData.LocalModsDirectory)
#if CLIENT
|| path.StartsWith(ConfigData.TempDownloadsDirectory)
#endif
)
{
return true;
}
if (!_fileListRead.ContainsKey(path))
{
return false;