OBT/1.2.0(Spring Update)

Sync with Upstream
This commit is contained in:
NotAlwaysTrue
2026-04-25 13:25:41 +08:00
committed by GitHub
parent 5207b381b7
commit 59bc21973a
421 changed files with 24090 additions and 11391 deletions
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using OneOf;
// ReSharper disable InconsistentNaming
namespace Barotrauma.LuaCs;
public interface IAssemblyManagementService : IPluginManagementService
{
/// <summary>
/// Searches for an assembly given it's fully qualified name, while excluding the contexts with the given Guids, if supplied.
/// </summary>
/// <param name="assemblyName">The assembly info.</param>
/// <param name="excludedContexts">Guids of excluded contexts.</param>
/// <returns><b>On Success:</b> The assembly. <br/><b>On Failure:</b> nothing.</returns>
FluentResults.Result<Assembly> GetLoadedAssembly(OneOf<AssemblyName, string> assemblyName, in Guid[] excludedContexts);
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using System.Xml.Linq;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs;
using Barotrauma.Networking;
using FluentResults;
namespace Barotrauma.LuaCs;
public partial interface IConfigService : IReusableService, ILuaConfigService
{
void RegisterSettingTypeInitializer<T>(string typeIdentifier, Func<(IConfigService ConfigService, IConfigInfo Info), T> settingFactory)
where T : class, ISettingBase;
Task<FluentResults.Result> LoadConfigsAsync(ImmutableArray<IConfigResourceInfo> configResources);
Task<FluentResults.Result> LoadConfigsProfilesAsync(ImmutableArray<IConfigResourceInfo> configProfileResources);
FluentResults.Result LoadSavedConfigsValues();
FluentResults.Result ApplyConfigProfile(ContentPackage package, string internalName);
FluentResults.Result DisposePackageData(ContentPackage package);
FluentResults.Result DisposeAllPackageData();
}
@@ -0,0 +1,16 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
namespace Barotrauma.LuaCs;
public interface IConsoleCommandsService : IService
{
void RegisterCommand(string name, string help, Action<string[]> onExecute, Func<string[][]> getValidArgs = null, bool isCheat = false);
void AssignOnExecute(string names, Action<string[]> onExecute);
#if SERVER
internal void AssignOnClientRequestExecute(string names, Action<Client, Vector2, string[]> onClientRequestExecute);
#endif
void RemoveCommand(string name);
void RemoveRegisteredCommands();
}
@@ -0,0 +1,52 @@
using System;
using System.Reflection;
using Barotrauma.LuaCs.Events;
using Barotrauma.LuaCs.Compatibility;
using Barotrauma.LuaCs;
namespace Barotrauma.LuaCs;
public interface IEventService : IReusableService, ILuaEventService
{
/// <summary>
///
/// </summary>
/// <param name="subscriber"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
FluentResults.Result Subscribe<T>(T subscriber) where T : class, IEvent<T>;
/// <summary>
///
/// </summary>
/// <param name="subscriber"></param>
/// <typeparam name="T"></typeparam>
void Unsubscribe<T>(T subscriber) where T : class, IEvent;
/// <summary>
/// Clears all subscribers for a given event type and removes any registration to the type.
/// </summary>
/// <typeparam name="T">The event type.</typeparam>
void ClearAllEventSubscribers<T>() where T : class, IEvent;
/// <summary>
/// Clears all subscribers lists.
/// </summary>
void ClearAllSubscribers();
/// <summary>
/// Invokes all alive subscribers of the given event using the provided invocation factory.
/// </summary>
/// <param name="action"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
FluentResults.Result PublishEvent<T>(Action<T> action) where T : class, IEvent<T>;
/// <summary>
/// Adds an event service that will receive all published events.
/// </summary>
/// <param name="eventService"></param>
void AddDispatcherEventService(IEventService eventService);
/// <summary>
/// Removes an event service from the dispatcher list.
/// </summary>
/// <param name="eventService"></param>
void RemoveDispatcherEventService(IEventService eventService);
}
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using System.Xml.Linq;
using Barotrauma.LuaCs.Data;
using FluentResults;
namespace Barotrauma.LuaCs;
public interface IParserService<in TSrc, TOut> : IService
{
Result<TOut> TryParseResource(TSrc src);
ImmutableArray<Result<TOut>> TryParseResources(IEnumerable<TSrc> sources);
}
public interface IParserServiceAsync<in TSrc, TOut> : IService
{
Task<Result<TOut>> TryParseResourceAsync(TSrc src);
Task<ImmutableArray<Result<TOut>>> TryParseResourcesAsync(IEnumerable<TSrc> sources);
}
public interface IParserServiceOneToManyAsync<in TSrc, TOut> : IService
{
Task<Result<ImmutableArray<TOut>>> TryParseResourcesAsync(TSrc src);
}
@@ -0,0 +1,59 @@
using System;
using Barotrauma.Networking;
using FluentResults;
using Microsoft.Xna.Framework;
namespace Barotrauma.LuaCs;
public readonly record struct PendingLog(string Message, Color? Color, ServerLog.MessageType MessageType);
public interface ILoggerSubscriber
{
void OnLog(PendingLog pendingLog);
}
/// <summary>
/// Provides console and debug logging services
/// </summary>
public interface ILoggerService : IReusableService
{
void Subscribe(ILoggerSubscriber subscriber);
void Unsubscribe(ILoggerSubscriber subscriber);
void ProcessLogs();
void HandleException(Exception exception, string prefix = null);
void LogError(string message);
void LogWarning(string message);
void LogMessage(string message, Color? serverColor = null, Color? clientColor = null);
void Log(string message, Color? color = null, ServerLog.MessageType messageType = ServerLog.MessageType.ServerMessage);
void LogResults(FluentResults.Result result);
#region DebugBuilds
void LogDebug(string message, Color? color = null);
void LogDebugWarning(string message);
void LogDebugError(string message);
#endregion
#region LegacyCompat_LuaCsLogger
public void HandleException(Exception ex, LuaCsMessageOrigin origin)
{
HandleException(ex, origin.ToString());
}
public void LogError(string message, LuaCsMessageOrigin origin)
{
LogError(message);
}
#endregion
}
public enum LuaCsMessageOrigin
{
LuaCs,
Unknown,
LuaMod,
CSharpMod,
}
@@ -0,0 +1,32 @@
namespace Barotrauma.LuaCs;
/// <summary>
/// Provides access to data from the current <see cref="LuaCsSetup"/>.
/// </summary>
public interface ILuaCsInfoProvider : IService
{
/// <summary>
/// Whether C# plugin code is enabled.
/// </summary>
public bool IsCsEnabled { get; }
/// <summary>
/// Whether usernames are anonymized or show in logs.
/// </summary>
public bool HideUserNamesInLogs { get; }
/// <summary>
/// Whether file system caching is enabled.
/// </summary>
public bool UseCaching { get; }
/// <summary>
/// The current state of the Execution State Machine.
/// </summary>
public RunState CurrentRunState { get; }
/// <summary>
/// Returns the best-matching LuaCsForBarotrauma package (enabled list > localMods > WorkshopMods).
/// </summary>
public ContentPackage LuaCsForBarotraumaPackage { get; }
}
@@ -0,0 +1,66 @@
#nullable enable
using System.Collections.Immutable;
using System.Threading.Tasks;
using Barotrauma.LuaCs.Data;
using MoonSharp.Interpreter;
namespace Barotrauma.LuaCs;
public interface ILuaScriptManagementService : IReusableService
{
/// <summary>
/// The running <see cref="Script"/> instance, if available.
/// </summary>
/// <remarks>
/// It is recommended to avoid using this directly if another API is available for the intended purposes.
/// </remarks>
Script? InternalScript { get; }
object? GetGlobalTableValue(string tableName);
FluentResults.Result<DynValue> DoString(string code);
DynValue? CallFunctionSafe(object luaFunction, params object[] args);
/// <summary>
/// Whether to enable/disable the file system caching for lua.
/// </summary>
/// <param name="useCaching"></param>
void SetCachingPolicy(bool useCaching);
/// <summary>
/// Parses and loads script sources (code) into a memory cache without executing it.
/// </summary>
/// <param name="resourcesInfo"></param>
/// <returns></returns>
// [Required]
Task<FluentResults.Result> LoadScriptResourcesAsync(ImmutableArray<ILuaScriptResourceInfo> resourcesInfo);
/// <summary>
/// Executes already loaded into memory scripts data, in the supplied order.
/// </summary>
/// <param name="executionOrder"></param>
/// <returns></returns>
// [Required]
FluentResults.Result ExecuteLoadedScripts(ImmutableArray<ILuaScriptResourceInfo> executionOrder, bool enableSandbox);
/// <summary>
///
/// </summary>
/// <param name="package"></param>
/// <returns></returns>
// [Required]
FluentResults.Result DisposePackageResources(ContentPackage package);
/// <summary>
/// Calls dispose on, and clears active refs for, currently running scripts. Does not clear caches.
/// </summary>
/// <returns></returns>
FluentResults.Result UnloadActiveScripts();
/// <summary>
/// Unloads all scripts and clears all caches/references.
/// </summary>
/// <returns></returns>
/// <remarks>May be functionally equivalent to <see cref="IReusableService.Reset"/></remarks>
FluentResults.Result DisposeAllPackageResources();
}
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs;
using FluentResults;
namespace Barotrauma.LuaCs;
public interface IModConfigService : IService
{
/// <summary>
/// Loads or dynamically generates a <see cref="IModConfigInfo"/> for the given <see cref="ContentPackage"/>.
/// <br/> Throws a <see cref="NullReferenceException"/> if the package is null.
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
Task<Result<IModConfigInfo>> CreateConfigAsync([NotNull]ContentPackage src);
Task<ImmutableArray<(ContentPackage Source, Result<IModConfigInfo> Config)>> CreateConfigsAsync(ImmutableArray<ContentPackage> src);
}
@@ -0,0 +1,39 @@
using System;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs;
using Barotrauma.LuaCs.Compatibility;
using Barotrauma.Networking;
namespace Barotrauma.LuaCs;
#if CLIENT
public delegate void NetMessageReceived(IReadMessage netMessage);
#elif SERVER
internal delegate void NetMessageReceived(IReadMessage netMessage, Client connection);
#endif
internal interface INetworkingService : IReusableService, ILuaCsNetworking, IEntityNetworkingService
{
bool IsActive { get; }
bool IsSynchronized { get; }
IWriteMessage Start(string netId);
IWriteMessage Start(Guid netId);
void Receive(string netId, NetMessageReceived action);
void Receive(Guid netId, NetMessageReceived action);
#if SERVER
void SendToClient(IWriteMessage netMessage, NetworkConnection connection = null, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable);
#elif CLIENT
void SendToServer(IWriteMessage netMessage, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable);
#endif
}
public interface IEntityNetworkingService
{
Guid GetNetworkIdForInstance(INetworkSyncVar var);
void RegisterNetVar(INetworkSyncVar netVar);
void DeregisterNetVar(INetworkSyncVar netVar);
void SendNetVar(INetworkSyncVar netVar);
void SendNetVar(INetworkSyncVar netVar, NetworkConnection connection);
}
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Threading.Tasks;
using Barotrauma.Extensions;
using Barotrauma.LuaCs.Data;
using FluentResults;
namespace Barotrauma.LuaCs;
public interface IPackageManagementService : IReusableService
{
public bool TryGetLoadedPackageByName(string name, out ContentPackage package);
public FluentResults.Result LoadPackageInfo(ContentPackage package);
public FluentResults.Result LoadPackagesInfo(ImmutableArray<ContentPackage> packages);
public FluentResults.Result ExecuteLoadedPackages(ImmutableArray<ContentPackage> executionOrder, bool executeCsAssemblies);
public FluentResults.Result SyncLoadedPackagesList(ImmutableArray<ContentPackage> packages);
public FluentResults.Result StopRunningPackages();
public FluentResults.Result UnloadPackage(ContentPackage package);
public FluentResults.Result UnloadPackages(ImmutableArray<ContentPackage> packages);
public FluentResults.Result UnloadAllPackages();
public ImmutableArray<ContentPackage> GetAllLoadedPackages();
public ImmutableArray<ContentPackage> GetLoadedUnrestrictedPackages();
public bool IsPackageRunning(ContentPackage package);
public bool IsAnyPackageLoaded();
public bool IsAnyPackageRunning();
public bool PackageContainsAnyRunnableResource(ContentPackage package);
public Result<IModConfigInfo> GetModConfigForPackage(ContentPackage package);
}
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using Barotrauma.LuaCs.Data;
using Microsoft.CodeAnalysis;
namespace Barotrauma.LuaCs;
public interface IPluginManagementService : IReusableService
{
/// <summary>
/// Gets all types in searched <see cref="IAssemblyLoaderService"/> that implement the type supplied.
/// </summary>
/// <param name="includeInterfaces"></param>
/// <param name="includeAbstractTypes"></param>
/// <param name="includeDefaultContext"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
FluentResults.Result<ImmutableArray<Type>> GetImplementingTypes<T>(
bool includeInterfaces = false,
bool includeAbstractTypes = false,
bool includeDefaultContext = true);
/// <summary>
/// Gets the <see cref="ContentPackage"/> that contains the plugin type.
/// </summary>
/// <param name="ownerPackage"></param>
/// <typeparam name="TPlugin"></typeparam>
/// <returns></returns>
bool TryGetPackageForPlugin<TPlugin>(out ContentPackage ownerPackage);
/// <summary>
/// Tries to find the type given the fully qualified name and filters.
/// </summary>
/// <param name="typeName"></param>
/// <param name="isByRefType"></param>
/// <param name="includeInterfaces"></param>
/// <param name="includeDefaultContext"></param>
/// <returns></returns>
Type GetType(string typeName, bool isByRefType = false, bool includeInterfaces = false, bool includeDefaultContext = true);
/// <summary>
///
/// </summary>
/// <param name="executionOrder"></param>
/// <param name="excludeAlreadyRunningPackages"></param>
/// <returns></returns>
FluentResults.Result ActivatePluginInstances(ImmutableArray<ContentPackage> executionOrder, bool excludeAlreadyRunningPackages = true);
/// <summary>
/// Loads the provided assembly resources in the order of their dependencies and intra-mod priority load order.
/// </summary>
/// <param name="resources"></param>
/// <returns>Success/Failure and list of failed resources, if any.</returns>
FluentResults.Result LoadAssemblyResources(ImmutableArray<IAssemblyResourceInfo> resources);
/// <summary>
/// Unloads all managed <see cref="IAssemblyPlugin"/>, <see cref="Assembly"/>, and <see cref="IAssemblyLoaderService"/>s.
/// </summary>
/// <returns>Success of the operation. <br/><b>Note: does not guarantee .NET runtime assembly unloading success.</b></returns>
FluentResults.Result UnloadManagedAssemblies();
}
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using Barotrauma.LuaCs.Data;
namespace Barotrauma.LuaCs;
public interface IPluginService : IReusableService
{
bool IsAssemblyLoaded(string friendlyName);
/// <summary>
/// Loads the assemblies for the given information
/// </summary>
/// <param name="assemblyResourcesInfo"></param>
/// <param name="injectServices"></param>
/// <param name="typeInstances"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
FluentResults.Result LoadAndInstanceTypes<T>(IEnumerable<IAssemblyResourceInfo> assemblyResourcesInfo, bool injectServices, out ImmutableArray<T> typeInstances) where T : class, IAssemblyPlugin;
FluentResults.Result<ImmutableArray<T>> GetLoadedPluginTypesInPackage<T>() where T : class, IAssemblyPlugin;
/// <summary>
/// Advances the loading/execution state of the plugin. IMPORTANT: You cannot set the execution state of plugins
/// to 'Disposed'. You must instead call the 'DisposePlugins' method.
/// </summary>
/// <param name="newState"></param>
/// <returns></returns>
FluentResults.Result AdvancePluginStates(PluginRunState newState);
/// <summary>
/// Disposes of all running plugins hosted by the service and releases their references to allow unloading.
/// </summary>
/// <returns>Success of the operation. Returns false if any plugin threw errors during disposal.</returns>
FluentResults.Result DisposePlugins();
/// <summary>
/// Gets the current plugin execution state.
/// </summary>
/// <returns></returns>
PluginRunState GetPluginRunState();
}
public enum PluginRunState
{
Instanced=0,
PreInitialization=1,
Initialized=2,
LoadingCompleted=3,
Disposed=4
}
@@ -0,0 +1,54 @@
using System.Collections.Immutable;
namespace Barotrauma.LuaCs;
public interface ISafeStorageService : IStorageService, ISafeStorageValidation { }
public interface ISafeStorageValidation
{
/// <summary>
/// Checks the given file path to see if it can be read. This includes any permissions, whitelists and OS checks.
/// </summary>
/// <param name="path">The absolute path to the file.</param>
/// <param name="readOnly">Whether to only check for read permissions only, or full RWM if false.</param>
/// <param name="checkWhitelistOnly">Whether to only check if the file is safe to access, without checking accessibility at the OS level.</param>
/// <returns>Whether the file is accessible.</returns>
bool IsFileAccessible(string path, bool readOnly, bool checkWhitelistOnly = true);
/// <summary>
/// Adds the given path to the specified whitelists.
/// </summary>
/// <param name="path">The path to the file, exactly as it will be passed to the Try(Load|Save) methods in <see cref="StorageService"/>.</param>
/// <param name="readOnly">Whether to add it to the read whitelist only, or Read+Write whitelists.</param>
void AddFileToWhitelist(string path, bool readOnly = true);
/// <summary>
/// Adds the given collection of file paths to whitelists (Read|+Write)
/// </summary>
/// <param name="paths">The paths to the files, formatted exactly as it will be passed to the Try(Load|Save) methods in <see cref="StorageService"/>.</param>
/// <param name="readOnly">Whether to add it to the read whitelist only, or Read+Write whitelists.</param>
void AddFilesToWhitelist(ImmutableArray<string> paths, bool readOnly = true);
/// <summary>
/// Removes the given path from all whitelists (Read|+Write).
/// </summary>
/// <param name="path"></param>
void RemoveFileFromAllWhitelists(string path);
/// <summary>
/// Sets the whitelist filtering for read-only file permissions for the instance. Overwrites previous list.
/// </summary>
/// <param name="filePaths">List of file paths allowed, as will be passed to the <see cref="StorageService"/> Try(Load|Save) methods.</param>
FluentResults.Result SetReadOnlyWhitelist(ImmutableArray<string> filePaths);
/// <summary>
/// Sets the whitelist filtering for read & write file permissions for the instance. Overwrites previous lists.
/// </summary>
/// <param name="filePaths">List of file paths allowed, as will be passed to the <see cref="StorageService"/> Try(Load|Save) methods.</param>
FluentResults.Result SetReadWriteWhitelist(ImmutableArray<string> filePaths);
/// <summary>
/// Deletes all paths from all white lists.
/// </summary>
void ClearAllWhitelists();
}
@@ -0,0 +1,43 @@
using System;
using Microsoft.Toolkit.Diagnostics;
namespace Barotrauma.LuaCs;
/// <summary>
/// Represents a <see cref="IReusableService"/> that is automatically instantiated at startup for the lifetime of the
/// <see cref="IServiceProvider"/> instance.
/// </summary>
public interface ISystem : IReusableService { }
/// <summary>
/// Defines a service that can be reset to it's post-constructor state and reused without needing to be disposed.
/// Intended for persistent services.
/// </summary>
public interface IReusableService : IService
{
/// <summary>
/// Returns the service to its original state (post-instantiation).
/// Allows a service instance to be reused without disposing of the instance.
/// </summary>
FluentResults.Result Reset();
}
/// <summary>
/// Base interface inherited by all services.
/// </summary>
/// <exception cref="ObjectDisposedException">Throws exception if `IsDisposed` return true.</exception>
public interface IService : IDisposable
{
bool IsDisposed { get; }
public void CheckDisposed()
{
if (IsDisposed)
ThrowHelper.ThrowObjectDisposedException($"Tried to call method on disposed object '{this.GetType().Name}'!");
}
static void CheckDisposed(IService service)
{
if (service.IsDisposed)
ThrowHelper.ThrowObjectDisposedException($"Tried to call method on disposed object '{service.GetType().Name}'!");
}
}
@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using LightInject;
namespace Barotrauma.LuaCs;
/// <summary>
/// Provides instancing and management of <see cref="IService"/>, <see cref="IReusableService"/>, and <see cref="ISystem"/>
/// instances.
/// </summary>
public interface IServicesProvider
{
#region Type_Registration
/// <summary>
/// Registers a type as a service for a given interface.
/// </summary>
/// <remarks>NOTE: <see cref="ISystem"/> services are forced to <see cref="ServiceLifetime.Singleton"/></remarks>
/// <param name="lifetime">The <see cref="ServiceLifetime"/> of the service when requested.</param>
/// <param name="lifetimeInstance">Custom lifetime instance.</param>
/// <typeparam name="TSvcInterface">Service interface.</typeparam>
/// <typeparam name="TService">Implementing service type.</typeparam>
void RegisterServiceType<TSvcInterface, TService>(ServiceLifetime lifetime, ILifetime lifetimeInstance = null) where TSvcInterface : class, IService where TService : class, IService, TSvcInterface;
/// <summary>
/// Registers a type as a service for a given interface that can be requested by name.
/// </summary>
/// <remarks>NOTE: <see cref="ISystem"/> services are forced to <see cref="ServiceLifetime.Singleton"/></remarks>
/// <param name="name">Name of the service for lookup.</param>
/// <param name="lifetime">The <see cref="ServiceLifetime"/> of the service when requested.</param>
/// <param name="lifetimeInstance">Custom lifetime instance.</param>
/// <typeparam name="TSvcInterface">Service interface.</typeparam>
/// <typeparam name="TService">Implementing service type.</typeparam>
void RegisterServiceType<TSvcInterface, TService>(string name, ServiceLifetime lifetime, ILifetime lifetimeInstance = null) where TSvcInterface : class, IService where TService : class, IService, TSvcInterface;
/// <summary>
/// Registers a factory for resolving the service type.
/// </summary>
/// <param name="factory"></param>
/// <typeparam name="TSvcInterface"></typeparam>
void RegisterServiceResolver<TSvcInterface>(Func<ServiceContainer, TSvcInterface> factory) where TSvcInterface : class, IService;
/// <summary>
/// Compiles/Generates IL for registered services and instantiates all registered <see cref="ISystem"/> types.
/// </summary>
public void CompileAndRun();
#endregion
#region Services_Instancing_Injection
/// <summary>
/// Injects services into the properties of already instanced objects.
/// </summary>
/// <param name="inst"></param>
/// <typeparam name="T"></typeparam>
void InjectServices<T>(T inst) where T : class;
/// <summary>
/// Tries to get a service for the given interface, returns success/failure.
/// </summary>
/// <param name="service"></param>
/// <typeparam name="TSvcInterface"></typeparam>
/// <returns></returns>
bool TryGetService<TSvcInterface>(out TSvcInterface service) where TSvcInterface : class, IService;
/// <summary>
/// Tries to get a service for the given interface, throws an exception upon failure.
/// </summary>
/// <typeparam name="TSvcInterface"></typeparam>
/// <returns></returns>
TSvcInterface GetService<TSvcInterface>() where TSvcInterface : class, IService;
/// <summary>
/// Tries to get a service for the given name and interface, returns success/failure.
/// </summary>
/// <param name="name"></param>
/// <param name="service"></param>
/// <typeparam name="TSvcInterface"></typeparam>
/// <returns></returns>
bool TryGetService<TSvcInterface>(string name, out TSvcInterface service) where TSvcInterface : class, IService;
/// <summary>
/// Called whenever a new service is created/instanced.
/// Args[0]: The interface type of the service.
/// Args[1]: The instance of the service.
/// </summary>
event System.Action<Type, IService> OnServiceInstanced;
#endregion
#region ActiveServices
/// <summary>
/// Returns all services for the given interface.
/// </summary>
/// <typeparam name="TSvc"></typeparam>
/// <returns></returns>
ImmutableArray<TSvc> GetAllServices<TSvc>() where TSvc : class, IService;
#endregion
// Notes: Left public due to the common use of Publicizers
#region Internal_Use
/// <summary>
/// Notes: Internal use only if hosted by LuaCsForBarotrauma. Disposes of all services and resets DI container. Warning: unable to dispose of services held by other objects.
/// </summary>
void DisposeAndReset();
#endregion
}
public enum ServiceLifetime
{
Transient, Singleton, PerThread, Invalid, Custom
}
@@ -0,0 +1,84 @@
using System;
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using FluentResults;
namespace Barotrauma.LuaCs;
public interface IStorageService : IService
{
bool UseCaching { get; set; }
/// <summary>
/// Deletes all cached file data.
/// </summary>
void PurgeCache();
/// <summary>
/// Deletes the data for the supplied file path from the data cache.
/// </summary>
/// <param name="absolutePath"></param>
void PurgeFileFromCache(string absolutePath);
/// <summary>
/// Deletes the data from the supplied file paths from the data cache.
/// </summary>
/// <param name="absolutePaths"></param>
void PurgeFilesFromCache(params string[] absolutePaths);
// -- local game folder storage
FluentResults.Result<XDocument> LoadLocalXml(ContentPackage package, string localFilePath);
FluentResults.Result<byte[]> LoadLocalBinary(ContentPackage package, string localFilePath);
FluentResults.Result<string> LoadLocalText(ContentPackage package, string localFilePath);
FluentResults.Result SaveLocalXml(ContentPackage package, string localFilePath, XDocument document);
FluentResults.Result SaveLocalBinary(ContentPackage package, string localFilePath, in byte[] bytes);
FluentResults.Result SaveLocalText(ContentPackage package, string localFilePath, in string text);
// async
Task<FluentResults.Result<XDocument>> LoadLocalXmlAsync(ContentPackage package, string localFilePath);
Task<FluentResults.Result<byte[]>> LoadLocalBinaryAsync(ContentPackage package, string localFilePath);
Task<FluentResults.Result<string>> LoadLocalTextAsync(ContentPackage package, string localFilePath);
Task<FluentResults.Result> SaveLocalXmlAsync(ContentPackage package, string localFilePath, XDocument document);
Task<FluentResults.Result> SaveLocalBinaryAsync(ContentPackage package, string localFilePath, byte[] bytes);
Task<FluentResults.Result> SaveLocalTextAsync(ContentPackage package, string localFilePath, string text);
// -- package directory
// singles
Result<XDocument> LoadPackageXml(ContentPath filePath);
Result<byte[]> LoadPackageBinary(ContentPath filePath);
Result<string> LoadPackageText(ContentPath filePath);
// collections
ImmutableArray<(ContentPath, Result<XDocument>)> LoadPackageXmlFiles(ImmutableArray<ContentPath> filePaths);
ImmutableArray<(ContentPath, Result<byte[]>)> LoadPackageBinaryFiles(ImmutableArray<ContentPath> filePaths);
ImmutableArray<(ContentPath, Result<string>)> LoadPackageTextFiles(ImmutableArray<ContentPath> filePaths);
FluentResults.Result<ImmutableArray<string>> FindFilesInPackage(ContentPackage package, string localSubfolder, string regexFilter, bool searchRecursively);
// async
// singles
Task<Result<XDocument>> LoadPackageXmlAsync(ContentPath filePath);
Task<Result<byte[]>> LoadPackageBinaryAsync(ContentPath filePath);
Task<Result<string>> LoadPackageTextAsync(ContentPath filePath);
// collections
Task<ImmutableArray<(ContentPath, Result<XDocument>)>> LoadPackageXmlFilesAsync(ImmutableArray<ContentPath> filePaths);
Task<ImmutableArray<(ContentPath, Result<byte[]>)>> LoadPackageBinaryFilesAsync(ImmutableArray<ContentPath> filePaths);
Task<ImmutableArray<(ContentPath, Result<string>)>> LoadPackageTextFilesAsync(ImmutableArray<ContentPath> filePaths);
// -- absolute paths
FluentResults.Result<XDocument> TryLoadXml(string filePath, Encoding encoding = null);
FluentResults.Result<string> TryLoadText(string filePath, Encoding encoding = null);
FluentResults.Result<byte[]> TryLoadBinary(string filePath);
FluentResults.Result TrySaveXml(string filePath, in XDocument document, Encoding encoding = null);
FluentResults.Result TrySaveText(string filePath, in string text, Encoding encoding = null);
FluentResults.Result TrySaveBinary(string filePath, in byte[] bytes);
FluentResults.Result<bool> FileExists(string filePath);
FluentResults.Result<bool> DirectoryExists(string directoryPath);
//async
Task<FluentResults.Result<XDocument>> TryLoadXmlAsync(string filePath, Encoding encoding = null);
Task<FluentResults.Result<string>> TryLoadTextAsync(string filePath, Encoding encoding = null);
Task<FluentResults.Result<byte[]>> TryLoadBinaryAsync(string filePath);
Task<FluentResults.Result> TrySaveXmlAsync(string filePath, XDocument document, Encoding encoding = null);
Task<FluentResults.Result> TrySaveTextAsync(string filePath, string text, Encoding encoding = null);
Task<FluentResults.Result> TrySaveBinaryAsync(string filePath, byte[] bytes);
}