diff --git a/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/Processing/ModConfigService.cs b/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/Processing/ModConfigService.cs deleted file mode 100644 index 0e46339e7..000000000 --- a/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/Processing/ModConfigService.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Threading.Tasks; -using System.Xml.Linq; -using Barotrauma.LuaCs.Data; -using FluentResults; - -namespace Barotrauma.LuaCs.Services.Processing; - -public partial class ModConfigService -{ - private partial async Task> GetModConfigInfoAsync(ContentPackage package, XElement root) - { - var asm = root.GetChildElements("Assembly").ToImmutableArray(); - var cfg = root.GetChildElements("Config").ToImmutableArray(); - var lua = root.GetChildElements("Lua").ToImmutableArray(); - - return FluentResults.Result.Ok(new ModConfigInfo() - { - Package = package, - PackageName = package.Name, - Assemblies = asm.Any() ? GetAssemblies(package, asm) : ImmutableArray.Empty, - Configs = cfg.Any() ? GetConfigs(package, cfg) : ImmutableArray.Empty, - ConfigProfiles = cfg.Any() ? GetConfigProfiles(package, cfg) : ImmutableArray.Empty, - LuaScripts = lua.Any() ? GetLuaScripts(package, lua) : ImmutableArray.Empty - }); - } -} diff --git a/Barotrauma/BarotraumaShared/Luatrauma.props b/Barotrauma/BarotraumaShared/Luatrauma.props index 5b7154571..ebc46700a 100644 --- a/Barotrauma/BarotraumaShared/Luatrauma.props +++ b/Barotrauma/BarotraumaShared/Luatrauma.props @@ -1,25 +1,24 @@ - - - - - - - - - - - - - - - - - - en - + --> + + en + diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs index d94311ee2..6b94165f4 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs @@ -40,7 +40,6 @@ namespace Barotrauma void RegisterServices() { _servicesProvider.RegisterServiceType(ServiceLifetime.Transient); - _servicesProvider.RegisterServiceType(ServiceLifetime.Singleton); _servicesProvider.RegisterServiceType(ServiceLifetime.Singleton); _servicesProvider.RegisterServiceType(ServiceLifetime.Singleton); _servicesProvider.RegisterServiceType(ServiceLifetime.Transient); @@ -55,15 +54,9 @@ namespace Barotrauma // TODO: INetworkingService // TODO: [Resource Converter/Parser Services] - // IResourceInfo wrappers and mutators. - _servicesProvider.RegisterServiceType, IAssembliesResourcesInfo>, ResourceInfoArrayPacker>(ServiceLifetime.Transient); - _servicesProvider.RegisterServiceType, IConfigsResourcesInfo>, ResourceInfoArrayPacker>(ServiceLifetime.Transient); - _servicesProvider.RegisterServiceType, IConfigProfilesResourcesInfo>, ResourceInfoArrayPacker>(ServiceLifetime.Transient); - _servicesProvider.RegisterServiceType, ILuaScriptsResourcesInfo>, ResourceInfoArrayPacker>(ServiceLifetime.Transient); - // Loaders and Processors (yes the naming is reversed, oops). - _servicesProvider.RegisterServiceType, ModConfigService>(ServiceLifetime.Transient); - _servicesProvider.RegisterServiceType, ModConfigService>(ServiceLifetime.Transient); + _servicesProvider.RegisterServiceType, ModConfigService>(ServiceLifetime.Transient); + _servicesProvider.RegisterServiceType, ModConfigService>(ServiceLifetime.Transient); _servicesProvider.RegisterServiceType(ServiceLifetime.Transient); // service config data diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/ConfigService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/ConfigService.cs index 2b31d3da4..47648cab3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/ConfigService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/ConfigService.cs @@ -24,11 +24,11 @@ namespace Barotrauma.LuaCs.Services; public partial class ConfigService : IConfigService { //--- Internals - public ConfigService(IConverterServiceAsync> configProfileResourceConverter, - IConverterServiceAsync> configResourceConverter, IEventService eventService, System.Lazy storageService) + public ConfigService(IParserServiceAsync> configProfileResourceParser, + IParserServiceAsync> configResourceParser, IEventService eventService, System.Lazy storageService) { - _configProfileResourceConverter = configProfileResourceConverter; - _configResourceConverter = configResourceConverter; + _configProfileResourceParser = configProfileResourceParser; + _configResourceParser = configResourceParser; _eventService = eventService; _storageService = storageService; this._base = this; @@ -47,8 +47,8 @@ public partial class ConfigService : IConfigService private readonly AsyncReaderWriterLock _disposeOpsLock = new(); // extern services - private readonly IConverterServiceAsync> _configResourceConverter; - private readonly IConverterServiceAsync> _configProfileResourceConverter; + private readonly IParserServiceAsync> _configResourceParser; + private readonly IParserServiceAsync> _configProfileResourceParser; private readonly IEventService _eventService; private readonly System.Lazy _storageService; @@ -318,7 +318,7 @@ public partial class ConfigService : IConfigService if (configResources.IsDefaultOrEmpty) return FluentResults.Result.Fail($"{nameof(LoadConfigsAsync)}: Array is empty."); - var results = await _configResourceConverter.TryParseResourcesAsync(configResources); + var results = await _configResourceParser.TryParseResourcesAsync(configResources); var ret = new FluentResults.Result(); foreach (var result in results) @@ -365,7 +365,7 @@ public partial class ConfigService : IConfigService if (configProfileResources.IsDefaultOrEmpty) return FluentResults.Result.Fail($"{nameof(LoadConfigsProfilesAsync)}: Array is empty."); - var results = await _configProfileResourceConverter.TryParseResourcesAsync(configProfileResources); + var results = await _configProfileResourceParser.TryParseResourcesAsync(configProfileResources); var ret = new FluentResults.Result(); foreach (var result in results) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ConfigIOService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ConfigIOService.cs index f07a01e8c..b82098744 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ConfigIOService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ConfigIOService.cs @@ -46,7 +46,7 @@ public class ConfigIOService : IConfigIOService try { - var infos = await _storageService.LoadPackageXmlFilesAsync(src.OwnerPackage, src.FilePaths); + var infos = await _storageService.LoadPackageXmlFilesAsync(src.OwnerPackage, [..src.FilePaths.Select(fp => fp.FullPath)]); if (infos.IsDefaultOrEmpty) return FluentResults.Result.Fail($"{nameof(TryParseResourceAsync)}: No resources found."); diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConfigIOService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConfigIOService.cs index 7361b6575..72d1dff10 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConfigIOService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConfigIOService.cs @@ -7,8 +7,8 @@ using Barotrauma.LuaCs.Services.Processing; namespace Barotrauma.LuaCs.Services.Processing; public interface IConfigIOService : IReusableService, - IConverterServiceAsync>, - IConverterServiceAsync> + IParserServiceAsync>, + IParserServiceAsync> { Task SaveConfigDataLocal(ContentPackage package, string configName, XElement serializedValue); Task>> LoadConfigDataFromLocal(ContentPackage package, string configName); diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConverterServiceDefinitions.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IHelperServiceDefinitions.cs similarity index 60% rename from Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConverterServiceDefinitions.cs rename to Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IHelperServiceDefinitions.cs index c64ffdb02..a1ddb3f94 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IConverterServiceDefinitions.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/IHelperServiceDefinitions.cs @@ -7,24 +7,14 @@ using FluentResults; namespace Barotrauma.LuaCs.Services.Processing; -public interface IConverterService : IService +public interface IParserService : IService { Result TryParseResource(TSrc src); ImmutableArray> TryParseResources(IEnumerable sources); } -public interface IConverterServiceAsync : IService +public interface IParserServiceAsync : IService { Task> TryParseResourceAsync(TSrc src); Task>> TryParseResourcesAsync(IEnumerable sources); } - -public interface IProcessorService : IService -{ - TOut Process(TSrc src); -} - -public interface IProcessorServiceAsync : IService -{ - Task ProcessAsync(TSrc src); -} diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ModConfigService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ModConfigService.cs index 8604bbe64..60dcbd4e1 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ModConfigService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ModConfigService.cs @@ -12,545 +12,81 @@ using FluentResults; namespace Barotrauma.LuaCs.Services.Processing; -public partial class ModConfigService : IConverterServiceAsync, IConverterService +public sealed class ModConfigService : IModConfigService { - private readonly IStorageService _storageService; - private readonly Lazy _packageManagementService; - private int _isDisposed; + private IStorageService _storageService; + private IParserServiceAsync _assemblyParserService; + private IParserServiceAsync _luaScriptParserService; + private IParserServiceAsync _configParserService; + private IParserServiceAsync _configProfileParserService; - private const string ModConfigFileName = "ModConfig.xml"; - private const string ModConfigRootName = "ModConfig"; - - public ModConfigService(IStorageService storageService, Lazy pms) + public ModConfigService(IStorageService storageService, + IParserServiceAsync assemblyParserService, + IParserServiceAsync luaScriptParserService, + IParserServiceAsync configParserService, + IParserServiceAsync configProfileParserService) { _storageService = storageService; - _packageManagementService = pms; - } + _assemblyParserService = assemblyParserService; + _luaScriptParserService = luaScriptParserService; + _configParserService = configParserService; + _configProfileParserService = configProfileParserService; + } + #region Disposal + public void Dispose() { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } + private int _isDisposed = 0; public bool IsDisposed { - get => ModUtils.Threading.GetBool(ref _isDisposed); - private set => ModUtils.Threading.SetBool(ref _isDisposed, value); + get => ModUtils.Threading.GetBool(ref _isDisposed); + protected set => ModUtils.Threading.SetBool(ref _isDisposed, value); } - public async Task> TryParseResourceAsync(ContentPackage src) + #endregion + + public async Task> CreateConfigAsync(ContentPackage src) { - ((IService)this).CheckDisposed(); - - // validate package if (src is null) - return FluentResults.Result.Fail("ContentPackage is null"); - if (_storageService.DirectoryExists(src.Path) is { } res && (res.IsFailed || !res.Value)) - return FluentResults.Result.Fail($"ContentPackage does not exist or cannot be accessed: {src.Path}"); + ArgumentNullException.ThrowIfNull($"{nameof(CreateConfigAsync)}: Source is null."); - // find ModConfig.xml or deep scan on fail (legacy) - if (await _storageService.LoadPackageXmlAsync(src, ModConfigFileName) is - { IsSuccess: true, Value: var modConfigXml } - && modConfigXml.Root is { Name.LocalName: ModConfigRootName } root) + if (await TryGetModConfigXmlAsync(src) is { IsSuccess: true, Value: { } config }) { - return await GetModConfigInfoAsync(src, root); + return await CreateFromConfigXmlAsync(config); } - // legacy mode - try - { - // we only supported assemblies and lua scripts - var asm = GetAssembliesLegacy(src); - var lua = GetLuaScriptsLegacy(src); + return await CreateFromLegacyAsync(src); + } - return new ModConfigInfo() - { - Assemblies = asm, - LuaScripts = lua, - Configs = ImmutableArray.Empty, - ConfigProfiles = ImmutableArray.Empty, - Package = src, - PackageName = src.Name - }; - } - catch (Exception e) + public async Task Config)>> CreateConfigsAsync(ImmutableArray src) + { + var builder = ImmutableArray.CreateBuilder<(ContentPackage Source, Result Config)>(); + + foreach (var package in src) { - return FluentResults.Result.Fail($"Unable to parse legacy content package: {src.Name}: {src.Path}"); + builder.Add((package, await CreateConfigAsync(package))); } + + return builder.ToImmutable(); + } + + //--- Helpers + private async Task> TryGetModConfigXmlAsync(ContentPackage src) + { + + } + + private async Task> CreateFromConfigXmlAsync(XElement src) + { + throw new NotImplementedException(); } - private partial Task> GetModConfigInfoAsync(ContentPackage package, XElement root); - - private ImmutableArray GetAssemblies(ContentPackage src, IEnumerable elements) + private async Task> CreateFromLegacyAsync(ContentPackage src) { - var builder = ImmutableArray.CreateBuilder(); - var elementsList = elements.ToImmutableArray(); - - if (GetFilesList(src, elementsList, "Assembly", "*.dll") - is not { IsSuccess: true, Value: { } xmlFiles }) - return ImmutableArray.Empty; - - foreach (var file in xmlFiles) - { - // get platform, culture and target architecture - var info = GetElementsAttributesData(file.Item1, file.Item2.First()); - - builder.Add(new AssemblyResourceInfo() - { - Optional = info.IsOptional, - FilePaths = file.Item2, - InternalName = info.Name, - LoadPriority = info.LoadPriority, - OwnerPackage = src, - SupportedPlatforms = info.SupportedPlatforms, - SupportedTargets = info.SupportedTargets, - FriendlyName = file.Item1.GetAttributeString("Name", info.Name), - IsScript = false - }); - } - - if (GetFilesList(src, elementsList, "Assembly", "*.cs") - is not { IsSuccess: true, Value: { } xmlFiles2 }) - return ImmutableArray.Empty; - - foreach (var file in xmlFiles2) - { - // get platform, culture and target architecture - var info = GetElementsAttributesData(file.Item1, file.Item2.First()); - - builder.Add(new AssemblyResourceInfo() - { - Optional = info.IsOptional, - FilePaths = file.Item2, - InternalName = info.Name, - LoadPriority = info.LoadPriority, - OwnerPackage = src, - SupportedPlatforms = info.SupportedPlatforms, - SupportedTargets = info.SupportedTargets, - FriendlyName = file.Item1.GetAttributeString("Name", info.Name), - IsScript = true - }); - } - - return builder.Count > 0 - ? builder.ToImmutable() - : ImmutableArray.Empty; + throw new NotImplementedException(); } - - private ImmutableArray GetConfigs(ContentPackage src, IEnumerable elements) - { - var builder = ImmutableArray.CreateBuilder(); - if (GetXmlFilesList(src, elements, "Config") - is not { IsSuccess: true, Value: { } xmlFiles }) - return ImmutableArray.Empty; - - foreach (var file in xmlFiles) - { - // get platform, culture and target architecture - var info = GetElementsAttributesData(file.Item1, file.Item2.First()); - - builder.Add(new ConfigResourceInfo() - { - Optional = info.IsOptional, - FilePaths = file.Item2, - InternalName = info.Name, - LoadPriority = info.LoadPriority, - OwnerPackage = src, - SupportedPlatforms = info.SupportedPlatforms, - SupportedTargets = info.SupportedTargets - }); - } - - return builder.Count > 0 - ? builder.ToImmutable() - : ImmutableArray.Empty; - } - - private ImmutableArray GetConfigProfiles(ContentPackage src, IEnumerable elements) - { - var builder = ImmutableArray.CreateBuilder(); - if (GetXmlFilesList(src, elements, "Config") - is not { IsSuccess: true, Value: { } xmlFiles }) - return ImmutableArray.Empty; - - foreach (var file in xmlFiles) - { - // get platform, culture and target architecture - var info = GetElementsAttributesData(file.Item1, file.Item2.First()); - - builder.Add(new ConfigProfileResourceInfo() - { - Optional = info.IsOptional, - FilePaths = file.Item2, - InternalName = info.Name, - LoadPriority = info.LoadPriority, - OwnerPackage = src, - SupportedPlatforms = info.SupportedPlatforms, - SupportedTargets = info.SupportedTargets - }); - } - - return builder.Count > 0 - ? builder.ToImmutable() - : ImmutableArray.Empty; - } - - private ImmutableArray GetLuaScripts(ContentPackage src, IEnumerable elements) - { - var builder = ImmutableArray.CreateBuilder(); - if (GetXmlFilesList(src, elements, "Config") - is not { IsSuccess: true, Value: { } xmlFiles }) - return ImmutableArray.Empty; - - foreach (var file in xmlFiles) - { - // get platform, culture and target architecture - var info = GetElementsAttributesData(file.Item1, file.Item2.First()); - - builder.Add(new LuaScriptsResourceInfo() - { - Optional = info.IsOptional, - FilePaths = file.Item2, - InternalName = info.Name, - LoadPriority = info.LoadPriority, - OwnerPackage = src, - SupportedPlatforms = info.SupportedPlatforms, - SupportedTargets = info.SupportedTargets, - IsAutorun = file.Item1.GetAttributeBool("RunFile", true) - }); - } - - return builder.Count > 0 - ? builder.ToImmutable() - : ImmutableArray.Empty; - } - - private Result)>> GetXmlFilesList(ContentPackage src, - IEnumerable elements, string elementNameCheck) => - GetFilesList(src, elements, elementNameCheck, "*.xml"); - - private Result)>> GetFilesList(ContentPackage src, - IEnumerable elements, string elementNameCheck, string filter) - { - var builder = ImmutableArray.CreateBuilder<(XElement, ImmutableArray)>(); - - if (elementNameCheck.IsNullOrWhiteSpace()) - throw new ArgumentNullException($"{nameof(GetXmlFilesList)}: The element check is null."); - - foreach (var element in elements) - { - if (element.Name.LocalName != elementNameCheck) - throw new ArgumentException("Element is not a Localization element"); - - if (element.GetAttributeString("Folder", string.Empty) is { } str - && !string.IsNullOrWhiteSpace(str)) - { - if (_storageService.FindFilesInPackage(src, str, filter, true) - is not { IsSuccess: true, Value: var fpList } || !fpList.Any()) - { - continue; - } - - foreach (var fileP in fpList) - builder.Add((element, fpList.ToImmutableArray())); - } - else if (element.GetAttributeString("File", string.Empty) is { } fileStr - && !string.IsNullOrWhiteSpace(fileStr) - && _storageService.GetAbsFromPackage(src, fileStr) is { IsSuccess: true, Value: var fp } - && _storageService.FileExists(fp) is { IsSuccess: true, Value: true }) - { - builder.Add((element, new [] { fileStr }.ToImmutableArray())); - } - } - - return builder.Count > 0 - ? FluentResults.Result.Ok(builder.ToImmutable()) - : FluentResults.Result.Fail($"No files found"); - } - - private ResourceAdditionalInfo GetElementsAttributesData(XElement element, string localPath) - { - return new ResourceAdditionalInfo( - element.GetAttributeString("Name", localPath), - GetSupportedPlatforms(element.GetAttributeString("Platform", "any")), - GetSupportedTargets(element.GetAttributeString("Target", "any")), - GetSupportedCultures(element), - element.GetAttributeBool("Optional", false), - element.GetAttributeInt("Priority", 0)); - - Platform GetSupportedPlatforms(string platformName) => platformName.ToLowerInvariant().Trim() switch - { - "windows" => Platform.Windows, - "linux" => Platform.Linux, - "osx" => Platform.OSX, - _ => Platform.Windows | Platform.Linux | Platform.OSX - }; - - Target GetSupportedTargets(string targetName) => targetName.ToLowerInvariant().Trim() switch - { - "client" => Target.Client, - "server" => Target.Server, - _ => Target.Client | Target.Server, - }; - - ImmutableArray GetSupportedCultures(XElement element) - { - var culture = element.GetAttributeString("Culture", string.Empty); - if (string.IsNullOrWhiteSpace(culture)) - return new[] { CultureInfo.InvariantCulture }.ToImmutableArray(); - var builder = ImmutableArray.CreateBuilder(); - var arr = culture.Split(','); - if (arr.Length == 0) - return new[] { CultureInfo.InvariantCulture }.ToImmutableArray(); - foreach (var culstr in arr) - { - if (string.IsNullOrWhiteSpace(culstr)) - continue; - try - { - builder.Add( - culstr.ToLowerInvariant().Trim() == "default" - ? CultureInfo.InvariantCulture - : CultureInfo.GetCultureInfo(culstr)); - } - catch (CultureNotFoundException e) - { - // This is the case if a culture is specified by the package that is not supported by the OS/.NET ENV. - // We ignore it since we can never use it. - continue; - } - } - - return builder.Count > 0 - ? builder.ToImmutable() - : new[] { CultureInfo.InvariantCulture }.ToImmutableArray(); - } - } - - private ImmutableArray GetAssembliesLegacy(ContentPackage src) - { - var builder = ImmutableArray.CreateBuilder(); - // server, linux - if (_storageService.FindFilesInPackage(src, "bin/Server/Linux", "*.dll", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesSrvLin}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = filesSrvLin, - FriendlyName = "AssembliesServerLinux", - InternalName = "AssembliesServerLinux", - IsScript = false, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Linux, - SupportedTargets = Target.Server - }); - } - - // server, osx - if (_storageService.FindFilesInPackage(src, "bin/Server/OSX", "*.dll", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesSrvOsx}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = filesSrvOsx, - FriendlyName = "AssembliesServerOSX", - InternalName = "AssembliesServerOSX", - IsScript = false, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.OSX, - SupportedTargets = Target.Server - }); - } - - // server, osx - if (_storageService.FindFilesInPackage(src, "bin/Server/Windows", "*.dll", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesSrvWin}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = filesSrvWin, - FriendlyName = "AssembliesServerWin", - InternalName = "AssembliesServerWin", - IsScript = false, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Windows, - SupportedTargets = Target.Server - }); - } - - // client, linux - if (_storageService.FindFilesInPackage(src, "bin/Client/Linux", "*.dll", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesCliLin}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = filesCliLin, - FriendlyName = "AssembliesClientLinux", - InternalName = "AssembliesClientLinux", - IsScript = false, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Linux, - SupportedTargets = Target.Client - }); - } - - // server, osx - if (_storageService.FindFilesInPackage(src, "bin/Client/OSX", "*.dll", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesCliOsx}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = filesCliOsx, - FriendlyName = "AssembliesClientOSX", - InternalName = "AssembliesClientOSX", - IsScript = false, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.OSX, - SupportedTargets = Target.Client - }); - } - - // server, osx - if (_storageService.FindFilesInPackage(src, "bin/Client/Windows", "*.dll", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesCliWin}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = filesCliWin, - FriendlyName = "AssembliesClientWin", - InternalName = "AssembliesClientWin", - IsScript = false, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Windows, - SupportedTargets = Target.Client - }); - } - - var sharedCsBuilder = ImmutableArray.CreateBuilder(); - if (_storageService.FindFilesInPackage(src, "CSharp/Shared", "*.cs", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false } files }) - { - sharedCsBuilder.AddRange(files); - } - - var filesCssShared = sharedCsBuilder.MoveToImmutable(); - var sharedFound = !filesCssShared.IsDefaultOrEmpty; - - // source files legacy: server - if (_storageService.FindFilesInPackage(src, "CSharp/Server", "*.cs", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesCssServer}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = sharedFound ? filesCssServer.Concat(filesCssShared).ToImmutableArray() : filesCssServer, - FriendlyName = "CssServer", - InternalName = "CssServer", - IsScript = true, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Linux | Platform.OSX | Platform.Windows, - SupportedTargets = Target.Server - }); - } - - // source files legacy: client - if (_storageService.FindFilesInPackage(src, "CSharp/Client", "*.cs", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false} filesCssClient}) - { - builder.Add(new AssemblyResourceInfo() - { - FilePaths = sharedFound ? filesCssClient.Concat(filesCssShared).ToImmutableArray() : filesCssClient, - FriendlyName = "CssClient", - InternalName = "CssClient", - IsScript = true, - LoadPriority = 1, - Optional = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Linux | Platform.OSX | Platform.Windows, - SupportedTargets = Target.Client - }); - } - - return builder.MoveToImmutable(); - } - private ImmutableArray GetLuaScriptsLegacy(ContentPackage src) - { - var builder = ImmutableArray.CreateBuilder(); - - if (_storageService.FindFilesInPackage(src, "Lua", "*.lua", true) - is { IsSuccess: true, Value: { IsDefaultOrEmpty: false } fileAll }) - { - builder.Add(new LuaScriptsResourceInfo() - { - FilePaths = fileAll.Where(path => !path.Contains("Autorun")).ToImmutableArray(), - InternalName = "LuaScriptsNormal", - Optional = false, - IsAutorun = false, - OwnerPackage = src, - SupportedPlatforms = Platform.Linux | Platform.OSX | Platform.Windows, - SupportedTargets = Target.Client | Target.Server - }); - - builder.Add(new LuaScriptsResourceInfo() - { - FilePaths = fileAll.Where(path => path.Contains("Autorun")).ToImmutableArray(), - InternalName = "LuaScriptsAutorun", - Optional = false, - IsAutorun = true, - OwnerPackage = src, - SupportedPlatforms = Platform.Linux | Platform.OSX | Platform.Windows, - SupportedTargets = Target.Client | Target.Server - }); - } - - return builder.MoveToImmutable(); - } - - public async Task>> TryParseResourcesAsync(IEnumerable sources) - { - ((IService)this).CheckDisposed(); - - var srcs = sources.ToImmutableArray(); - var results = new AsyncLocal>>(); - await srcs.ParallelForEachAsync(async pkg => - { - try - { - results.Value.Enqueue(await TryParseResourceAsync(pkg)); - } - catch (Exception e) - { - // this should never happen but this is to stop partial execution exit. - results.Value.Enqueue( - FluentResults.Result.Fail($"Failed to parse package {pkg?.Name}: {e.Message}")); - } - }); - return results.Value.ToImmutableArray(); - } - - public Result TryParseResource(ContentPackage src) => - TryParseResourceAsync(src).GetAwaiter().GetResult(); - public ImmutableArray> TryParseResources(IEnumerable sources) => - TryParseResourcesAsync(sources.ToImmutableArray()).GetAwaiter().GetResult(); - - private record ResourceAdditionalInfo( - string Name, - Platform SupportedPlatforms, - Target SupportedTargets, - ImmutableArray SupportedCultures, - bool IsOptional, - int LoadPriority); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ResourceInfoProcessors.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ResourceInfoProcessors.cs deleted file mode 100644 index d6fb94b32..000000000 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/Processing/ResourceInfoProcessors.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Barotrauma.LuaCs.Data; - -namespace Barotrauma.LuaCs.Services.Processing; - -public partial class ResourceInfoArrayPacker : - IProcessorService, IAssembliesResourcesInfo>, - IProcessorService, IConfigsResourcesInfo>, - IProcessorService, IConfigProfilesResourcesInfo>, - IProcessorService, ILuaScriptsResourcesInfo> -{ - private bool _isDisposed; - public IAssembliesResourcesInfo Process(IReadOnlyList src) - { - return new AssemblyResourcesInfo(src.ToImmutableArray()); - } - - public IConfigsResourcesInfo Process(IReadOnlyList src) - { - return new ConfigResourcesInfo(src.ToImmutableArray()); - } - - public IConfigProfilesResourcesInfo Process(IReadOnlyList src) - { - return new ConfigProfilesResourcesInfo(src.ToImmutableArray()); - } - - public ILuaScriptsResourcesInfo Process(IReadOnlyList src) - { - return new LuaScriptsResourcesInfo(src.ToImmutableArray()); - } - - public void Dispose() - { - // Stateless class - GC.SuppressFinalize(this); - IsDisposed = true; - } - - public bool IsDisposed - { - get => _isDisposed; - set => _isDisposed = value; - } -} diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/StorageService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/StorageService.cs index 54730328f..d1650b962 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/StorageService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/StorageService.cs @@ -15,6 +15,7 @@ using Barotrauma.LuaCs.Data; using Barotrauma.Steam; using FluentResults; using FluentResults.LuaCs; +using Microsoft.Toolkit.Diagnostics; using Error = FluentResults.Error; using Path = Barotrauma.IO.Path; @@ -98,49 +99,49 @@ public class StorageService : IStorageService } public virtual FluentResults.Result LoadLocalXml(ContentPackage package, string localFilePath) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TryLoadXml(r.Value) : r.ToResult(); public virtual FluentResults.Result LoadLocalBinary(ContentPackage package, string localFilePath) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TryLoadBinary(r.Value) : r.ToResult(); public virtual FluentResults.Result LoadLocalText(ContentPackage package, string localFilePath) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TryLoadText(r.Value) : r.ToResult(); public virtual FluentResults.Result SaveLocalXml(ContentPackage package, string localFilePath, XDocument document) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TrySaveXml(r.Value, document) : r.ToResult(); public virtual FluentResults.Result SaveLocalBinary(ContentPackage package, string localFilePath, in byte[] bytes) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TrySaveBinary(r.Value, bytes) : r.ToResult(); public virtual FluentResults.Result SaveLocalText(ContentPackage package, string localFilePath, in string text) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TrySaveText(r.Value, text) : r.ToResult(); public virtual async Task> LoadLocalXmlAsync(ContentPackage package, string localFilePath) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TryLoadXmlAsync(r.Value) : r.ToResult(); public virtual async Task> LoadLocalBinaryAsync(ContentPackage package, string localFilePath) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TryLoadBinaryAsync(r.Value) : r.ToResult(); public virtual async Task> LoadLocalTextAsync(ContentPackage package, string localFilePath) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TryLoadTextAsync(r.Value) : r.ToResult(); public virtual async Task SaveLocalXmlAsync(ContentPackage package, string localFilePath, XDocument document) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TrySaveXmlAsync(r.Value, document) : r.ToResult(); public virtual async Task SaveLocalBinaryAsync(ContentPackage package, string localFilePath, byte[] bytes) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TrySaveBinaryAsync(r.Value, bytes) : r.ToResult(); public virtual async Task SaveLocalTextAsync(ContentPackage package, string localFilePath, string text) => - GetAbsFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromLocal(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TrySaveTextAsync(r.Value, text) : r.ToResult(); public virtual FluentResults.Result LoadPackageXml(ContentPackage package, string localFilePath) => - GetAbsFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TryLoadXml(r.Value) : r.ToResult(); public virtual FluentResults.Result LoadPackageBinary(ContentPackage package, string localFilePath) => - GetAbsFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TryLoadBinary(r.Value) : r.ToResult(); public virtual FluentResults.Result LoadPackageText(ContentPackage package, string localFilePath) => - GetAbsFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? TryLoadText(r.Value) : r.ToResult(); @@ -181,7 +182,7 @@ public class StorageService : IStorageService public virtual FluentResults.Result> FindFilesInPackage(ContentPackage package, string localSubfolder, string regexFilter, bool searchRecursively) { ((IService)this).CheckDisposed(); - var r = GetAbsFromPackage(package, localSubfolder); + var r = GetAbsoluePathFromPackage(package, localSubfolder); if (r is { IsFailed: true }) return r.ToResult(); var builder = ImmutableArray.CreateBuilder<(string, FluentResults.Result>)>(); @@ -192,15 +193,15 @@ public class StorageService : IStorageService } public virtual async Task> LoadPackageXmlAsync(ContentPackage package, string localFilePath) => - GetAbsFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TryLoadXmlAsync(r.Value) : r.ToResult(); public virtual async Task> LoadPackageBinaryAsync(ContentPackage package, string localFilePath) => - GetAbsFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TryLoadBinaryAsync(r.Value) : r.ToResult(); public virtual async Task> LoadPackageTextAsync(ContentPackage package, string localFilePath) => - GetAbsFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } + GetAbsoluePathFromPackage(package, localFilePath) is var r && r is { IsSuccess: true, Value: not null } ? await TryLoadTextAsync(r.Value) : r.ToResult(); public virtual async Task)>> LoadPackageXmlFilesAsync(ContentPackage package, ImmutableArray localFilePaths) @@ -529,7 +530,7 @@ public class StorageService : IStorageService .WithMetadata(MetadataType.ExceptionObject, this) .WithMetadata(MetadataType.Sources, localfp); - private FluentResults.Result GetAbsFromLocal(ContentPackage package, string localFilePath) + private FluentResults.Result GetAbsoluePathFromLocal(ContentPackage package, string localFilePath) { if (Path.IsPathRooted(localFilePath)) { @@ -539,13 +540,7 @@ public class StorageService : IStorageService .WithMetadata(MetadataType.RootObject, localFilePath)); } - if (package is null) - { - return new FluentResults.Result().WithError( - new Error($"{nameof(GetAbsFromPackage)} The package reference for {localFilePath} is null!") - .WithMetadata(MetadataType.ExceptionObject, this) - .WithMetadata(MetadataType.RootObject, localFilePath)); - } + Guard.IsNotNull(package, nameof(package)); return new FluentResults.Result().WithSuccess($"Path constructed") .WithValue(System.IO.Path.GetFullPath(System.IO.Path.Combine( @@ -556,15 +551,9 @@ public class StorageService : IStorageService localFilePath))); } - public FluentResults.Result GetAbsFromPackage(ContentPackage package, string localFilePath) + public FluentResults.Result GetAbsoluePathFromPackage(ContentPackage package, string localFilePath) { - if (package is null) - { - return new FluentResults.Result().WithError( - new Error($"{nameof(GetAbsFromPackage)} The package reference for {localFilePath} is null!") - .WithMetadata(MetadataType.ExceptionObject, this) - .WithMetadata(MetadataType.RootObject, localFilePath)); - } + Guard.IsNotNull(package, nameof(package)); if (localFilePath.IsNullOrWhiteSpace()) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IModConfigInfo.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IModConfigInfo.cs new file mode 100644 index 000000000..78bac94aa --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IModConfigInfo.cs @@ -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.Services.Processing; +using FluentResults; + +namespace Barotrauma.LuaCs.Services; + +public interface IModConfigService : IService +{ + /// + /// Loads or dynamically generates a for the given . + ///
Throws a if the package is null. + ///
+ /// + /// + Task> CreateConfigAsync([NotNull]ContentPackage src); + Task Config)>> CreateConfigsAsync(ImmutableArray src); +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IStorageService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IStorageService.cs index 860a8eb6e..58ca07d55 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IStorageService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/_Interfaces/IStorageService.cs @@ -53,7 +53,7 @@ public interface IStorageService : IService ImmutableArray<(string, FluentResults.Result)> LoadPackageBinaryFiles(ContentPackage package, ImmutableArray localFilePaths); ImmutableArray<(string, FluentResults.Result)> LoadPackageTextFiles(ContentPackage package, ImmutableArray localFilePaths); FluentResults.Result> FindFilesInPackage(ContentPackage package, string localSubfolder, string regexFilter, bool searchRecursively); - FluentResults.Result GetAbsFromPackage(ContentPackage package, string localFilePath); + FluentResults.Result GetAbsoluePathFromPackage(ContentPackage package, string localFilePath); // async // singles Task> LoadPackageXmlAsync(ContentPackage package, string localFilePath);