[Milestone] PackageManagementService completed.

- ContentPackageInfoLookup Service completed.
- Implemented ModConfigService.cs
- Implemented some of the resource processors.
This commit is contained in:
MapleWheels
2025-02-26 12:48:34 -05:00
committed by Maplewheels
parent cb88d215fa
commit 52d920d969
78 changed files with 2331 additions and 422 deletions
@@ -16,6 +16,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Barotrauma.LuaCs.Events;
using static Barotrauma.FabricationRecipe;
namespace Barotrauma
@@ -665,8 +666,6 @@ namespace Barotrauma
bool.TryParse(args[3], out luaCsEnabled);
}
if (luaCsEnabled) { GameMain.LuaCs.Initialize(); }
GameMain.MainMenuScreen.QuickStart(fixedSeed: false, subName, difficulty, levelGenerationParams);
}, getValidArgs: () => new[] { SubmarineInfo.SavedSubmarines.Select(s => s.Name).Distinct().OrderBy(s => s).ToArray() }));
@@ -4226,7 +4225,8 @@ namespace Barotrauma
commands.Add(new Command("cl_lua", $"cl_lua: Runs a string on the client.", (string[] args) =>
{
if (GameMain.Client != null && !GameMain.Client.HasPermission(ClientPermissions.ConsoleCommands))
throw new NotImplementedException();
/*if (GameMain.Client != null && !GameMain.Client.HasPermission(ClientPermissions.ConsoleCommands))
{
ThrowError("Command not permitted.");
return;
@@ -4245,12 +4245,12 @@ namespace Barotrauma
catch(Exception ex)
{
LuaCsLogger.HandleException(ex, LuaCsMessageOrigin.LuaMod);
}
}*/
}));
commands.Add(new Command("cl_reloadlua|cl_reloadcs|cl_reloadluacs", "Re-initializes the LuaCs environment.", (string[] args) =>
{
GameMain.LuaCs.Initialize();
GameMain.LuaCs.EventService.PublishEvent<IEventReloadAllPackages>(sub => sub.OnReloadAllPackages());
}));
commands.Add(new Command("cl_toggleluadebug", "Toggles the MoonSharp Debug Server.", (string[] args) =>
@@ -4262,7 +4262,8 @@ namespace Barotrauma
int.TryParse(args[0], out port);
}
GameMain.LuaCs.ToggleDebugger(port);
throw new NotImplementedException();
//GameMain.LuaCs.ToggleDebugger(port);
}));
}
@@ -1299,6 +1299,19 @@ namespace Barotrauma
{
IsExiting = true;
CreatureMetrics.Save();
try
{
if (_luaCs is not null)
{
_luaCs.Dispose();
_luaCs = null;
}
}
catch (Exception e)
{
DebugConsole.ThrowError($"Error while disposing of LuaCsForBarotrauma: {e.Message} | {e.StackTrace}");
}
DebugConsole.NewMessage("Exiting...");
Client?.Quit();
SteamManager.ShutDown();
@@ -1,18 +0,0 @@
using Microsoft.Xna.Framework;
namespace Barotrauma.LuaCs.Configuration;
public record DisplayableData : IDisplayableData
{
public string InternalName { get; init; }
public ContentPackage OwnerPackage { get; init; }
public string FallbackPackageName { get; init; }
public string DisplayName { get; init; }
public string DisplayModName { get; init; }
public string DisplayCategory { get; init; }
public string Tooltip { get; init; }
public string ImageIcon { get; init; }
public Point IconResolution { get; init; }
public bool ShowWhenNotLoaded { get; init; }
public string Description { get; init; }
}
@@ -1,6 +0,0 @@
using Barotrauma.LuaCs.Configuration;
using Barotrauma.LuaCs.Data;
namespace Barotrauma.LuaCs.Configuration;
public partial interface IConfigBase : IDisplayableData, IDisplayableInitialize { }
@@ -1,63 +0,0 @@
using System.Numerics;
using Barotrauma.LuaCs.Data;
using Microsoft.Xna.Framework;
namespace Barotrauma.LuaCs.Configuration;
/// <summary>
/// Contains the Display Data for use with Menus.
/// </summary>
public interface IDisplayableData : IDataInfo
{
/// <summary>
/// The name to display in GUIs and Menus.
/// </summary>
string DisplayName { get; }
/// <summary>
/// The mod name to display in GUIs and Menus.
/// </summary>
string DisplayModName { get; }
/// <summary>
/// Category this instance falls under. Used by menus when filtering by category.
/// </summary>
string DisplayCategory { get; }
/// <summary>
/// The tooltip shown on hover.
/// </summary>
string Tooltip { get; }
/// <summary>
/// The fully qualified filepath to the image icon for this config.
/// </summary>
string ImageIcon { get; }
/// <summary>
/// Required if ImageIcon is set. X,Y resolution of the image.
/// </summary>
Point IconResolution { get; }
/// <summary>
/// Whether to show the entry in the menu when not loaded.
/// </summary>
bool ShowWhenNotLoaded { get; }
/// <summary>
/// What does this setting do?
/// </summary>
string Description { get; }
}
public interface IDisplayableInitialize
{
void Initialize(IDisplayableData values);
// copy this as needed
/*public void Initialize(IDisplayableData values)
{
this.InternalName = values.InternalName;
this.OwnerPackage = values.OwnerPackage;
this.DisplayName = values.DisplayName;
this.DisplayModName = values.DisplayModName;
this.DisplayCategory = values.DisplayCategory;
this.Tooltip = values.Tooltip;
this.ImageIcon = values.ImageIcon;
this.IconResolution = values.IconResolution;
this.ShowWhenNotLoaded = values.ShowWhenNotLoaded;
}*/
}
@@ -5,7 +5,7 @@ namespace Barotrauma.LuaCs.Data;
public partial record ModConfigInfo : IModConfigInfo
{
public ImmutableArray<IStylesResourceInfo> StylesResourceInfos { get; init; }
public ImmutableArray<IStylesResourceInfo> Styles { get; init; }
}
public record StylesResourceInfo : IStylesResourceInfo
@@ -18,6 +18,6 @@ public record StylesResourceInfo : IStylesResourceInfo
public ImmutableArray<CultureInfo> SupportedCultures { get; init; }
public string InternalName { get; init; }
public ContentPackage OwnerPackage { get; init; }
public string FallbackPackageName { get; }
public ImmutableArray<IPackageDependencyInfo> Dependencies { get; init; }
public string FallbackPackageName { get; init; }
public ImmutableArray<IPackageDependency> Dependencies { get; init; }
}
@@ -2,4 +2,18 @@ using Barotrauma.LuaCs.Configuration;
namespace Barotrauma.LuaCs.Data;
public partial interface IConfigInfo : IDisplayableData { }
public partial interface IConfigInfo
{
/// <summary>
/// Should this config be displayed in end-user menus.
/// </summary>
bool ShowInMenus { get; }
/// <summary>
/// User-friendly on-hover tooltip text or Localization Token.
/// </summary>
string Tooltip { get; }
/// <summary>
/// Icon for display in menus, if available.
/// </summary>
string ImageIconPath { get; }
}
@@ -4,12 +4,12 @@ namespace Barotrauma.LuaCs.Data;
public partial interface IModConfigInfo : IStylesResourcesInfo { }
public interface IStylesResourceInfo : IResourceInfo, IResourceCultureInfo, IPackageInfo, IPackageDependenciesInfo { }
public interface IStylesResourceInfo : IResourceInfo, IResourceCultureInfo, IDataInfo, IPackageDependenciesInfo { }
public interface IStylesResourcesInfo
{
/// <summary>
/// Collection of loadable styles data.
/// </summary>
ImmutableArray<IStylesResourceInfo> StylesResourceInfos { get; }
ImmutableArray<IStylesResourceInfo> Styles { get; }
}
@@ -57,6 +57,9 @@ namespace Barotrauma
public static void CheckUpdate()
{
throw new NotImplementedException();
/*// TODO: Rewrite this to not rely on LuaCsSetup.
if (!File.Exists(LuaCsSetup.VersionFile)) { return; }
ContentPackage luaPackage = LuaCsSetup.GetPackage(new SteamWorkshopId(GameMain.LuaCs.LuaForBarotraumaSteamId?.Value ?? 0));
@@ -116,6 +119,7 @@ namespace Barotrauma
msg.Close();
return true;
};
*/
}
}
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using Barotrauma.LuaCs.Configuration;
using Barotrauma.LuaCs.Networking;
using Barotrauma.LuaCs.Services;
using Barotrauma.Networking;
namespace Barotrauma.LuaCs.Services;
@@ -0,0 +1,8 @@
using Barotrauma.Networking;
namespace Barotrauma.LuaCs.Services;
internal partial interface INetworkingService : IReusableService
{
void NetMessageReceived(IReadMessage message, ServerPacketHeader header);
}
@@ -6,7 +6,7 @@ namespace Barotrauma.LuaCs.Services;
/// <summary>
/// Loads XML Style assets from the given content package.
/// </summary>
public interface IStylesService : IReusableService
public interface IStylesService : IService
{
/// <summary>
/// Tries to load the styles file for the given <see cref="ContentPackage"/> and path into a new <see cref="UIStyleProcessor"/> instance.
@@ -3,9 +3,9 @@ using Barotrauma.Networking;
using System;
using System.Collections.Generic;
namespace Barotrauma.LuaCs.Networking;
namespace Barotrauma.LuaCs.Services;
partial class NetworkingService
partial class NetworkingService : INetworkingService
{
private Dictionary<ushort, Queue<IReadMessage>> receiveQueue = new Dictionary<ushort, Queue<IReadMessage>>();
@@ -44,6 +44,11 @@ partial class NetworkingService
}
}
public void NetMessageReceived(IReadMessage message, ServerPacketHeader header)
{
throw new NotImplementedException();
}
public INetWriteMessage Start(Guid netId)
{
var message = new WriteOnlyMessage();
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs.Services.Processing;
using FluentResults;
// ReSharper disable UseCollectionExpression
namespace Barotrauma.LuaCs.Services;
public partial class PackageManagementService : IPackageManagementService
{
public PackageManagementService(
IConverterServiceAsync<ContentPackage, IModConfigInfo> modConfigParserService,
IProcessorService<IReadOnlyList<IAssemblyResourceInfo>, IAssembliesResourcesInfo> assemblyInfoConverter,
IProcessorService<IReadOnlyList<IConfigResourceInfo>, IConfigsResourcesInfo> configsInfoConverter,
IProcessorService<IReadOnlyList<IConfigProfileResourceInfo>, IConfigProfilesResourcesInfo> configProfilesConverter,
IProcessorService<IReadOnlyList<ILocalizationResourceInfo>, ILocalizationsResourcesInfo> localizationsConverter,
IProcessorService<IReadOnlyList<ILuaScriptResourceInfo>, ILuaScriptsResourcesInfo> luaScriptsConverter,
IPackageInfoLookupService packageInfoLookupService, Func<IReadOnlyList<IStylesResourceInfo>, IStylesResourcesInfo> stylesInfoConverter)
{
_stylesInfoConverter = stylesInfoConverter;
_modConfigParserService = modConfigParserService;
_assemblyInfoConverter = assemblyInfoConverter;
_configsInfoConverter = configsInfoConverter;
_configProfilesConverter = configProfilesConverter;
_localizationsConverter = localizationsConverter;
_luaScriptsConverter = luaScriptsConverter;
_packageInfoLookupService = packageInfoLookupService;
}
private readonly Func<IReadOnlyList<IStylesResourceInfo>, IStylesResourcesInfo> _stylesInfoConverter;
public ImmutableArray<IStylesResourceInfo> Styles => _modInfos.IsEmpty ? ImmutableArray<IStylesResourceInfo>.Empty
: _modInfos.SelectMany(kvp => kvp.Value.Styles).ToImmutableArray();
public Result<IStylesResourcesInfo> GetStylesInfos(ContentPackage package, bool onlySupportedResources = true)
{
((IService)this).CheckDisposed();
if (package is null)
return FluentResults.Result.Fail($"{nameof(GetStylesInfos)}: ContentPackage is null.");
if (_modInfos.TryGetValue(package, out var result))
return FluentResults.Result.Ok<IStylesResourcesInfo>(_stylesInfoConverter(onlySupportedResources?
result.Styles.Where(r =>
(r.SupportedPlatforms & ModUtils.Environment.CurrentPlatform) > 0
&& (r.SupportedTargets & ModUtils.Environment.CurrentTarget) > 0).ToImmutableArray()
: result.Styles
));
return FluentResults.Result.Fail(
$"{nameof(GetStylesInfos)}: ContentPackage {package.Name} is not registered.");
}
public Result<IStylesResourcesInfo> GetStylesInfos(IReadOnlyList<ContentPackage> packages, bool onlySupportedResources = true)
{
((IService)this).CheckDisposed();
if (packages is null || packages.Count == 0)
return FluentResults.Result.Fail($"{nameof(GetStylesInfos)}: ContentPackage list is null or empty.");
var builder = ImmutableArray.CreateBuilder<IStylesResourceInfo>();
foreach (var package in packages)
{
if (_modInfos.TryGetValue(package, out var result) && result.Styles is { IsEmpty: false })
{
builder.AddRange(onlySupportedResources?
result.Styles.Where(r =>
(r.SupportedPlatforms & ModUtils.Environment.CurrentPlatform) > 0
&& (r.SupportedTargets & ModUtils.Environment.CurrentTarget) > 0).ToImmutableArray()
: result.Styles);
}
}
return FluentResults.Result.Ok(_stylesInfoConverter(builder.MoveToImmutable()));
}
public async Task<Result<IStylesResourcesInfo>> GetStylesInfosAsync(IReadOnlyList<ContentPackage> packages, bool onlySupportedResources = true)
{
return await Task.Run(() => GetStylesInfos(packages, onlySupportedResources));
}
}
@@ -1,9 +0,0 @@
using System.Xml.Linq;
using Barotrauma.LuaCs.Data;
namespace Barotrauma.LuaCs.Services.Processing;
#region XmlToResourceParsers
public interface IXmlStylesToResConverterService : IXmlResourceConverterService<IStylesResourceInfo> { }
#endregion
@@ -0,0 +1,39 @@
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<Result<IModConfigInfo>> GetModConfigInfoAsync(ContentPackage package, XElement root)
{
var asm = root.GetChildElements("Assembly").ToImmutableArray();
var loc = root.GetChildElements("Localization").ToImmutableArray();
var cfg = root.GetChildElements("Config").ToImmutableArray();
var lua = root.GetChildElements("Lua").ToImmutableArray();
var stl = root.GetChildElements("Style").ToImmutableArray();
return FluentResults.Result.Ok<IModConfigInfo>(new ModConfigInfo()
{
Package = package,
PackageName = package.Name,
Assemblies = asm.Any() ? GetAssemblies(package, asm) : ImmutableArray<IAssemblyResourceInfo>.Empty,
Localizations = loc.Any() ? GetLocalizations(package, loc) : ImmutableArray<ILocalizationResourceInfo>.Empty,
Configs = cfg.Any() ? GetConfigs(package, cfg) : ImmutableArray<IConfigResourceInfo>.Empty,
ConfigProfiles = cfg.Any() ? GetConfigProfiles(package, cfg) : ImmutableArray<IConfigProfileResourceInfo>.Empty,
LuaScripts = lua.Any() ? GetLuaScripts(package, lua) : ImmutableArray<ILuaScriptResourceInfo>.Empty,
Styles = stl.Any() ? GetStyles(package, stl) : ImmutableArray<IStylesResourceInfo>.Empty
});
}
private ImmutableArray<IStylesResourceInfo> GetStyles(ContentPackage src, IEnumerable<XElement> elements)
{
throw new NotImplementedException();
}
}
@@ -116,10 +116,5 @@ public class StylesService : IStylesService
GC.SuppressFinalize(this);
}
public FluentResults.Result Reset()
{
return UnloadAllStyles();
}
public bool IsDisposed { get; private set; }
}
@@ -2905,8 +2905,6 @@ namespace Barotrauma.Networking
public void Quit()
{
GameMain.LuaCs.Stop();
ClientPeer?.Close(PeerDisconnectPacket.WithReason(DisconnectReason.Disconnected));
GUIMessageBox.MessageBoxes.RemoveAll(c => c?.UserData is RoundSummary);
@@ -542,8 +542,10 @@ namespace Barotrauma
}
};
string version = File.Exists(LuaCsSetup.VersionFile) ? File.ReadAllText(LuaCsSetup.VersionFile) : "Github";
// TODO: Implement version reading.
//string version = File.Exists(LuaCsSetup.VersionFile) ? File.ReadAllText(LuaCsSetup.VersionFile) : "Github";
string version = "NOT_IMPLEMENTED";
new GUITextBlock(new RectTransform(new Point(300, 30), Frame.RectTransform, Anchor.TopLeft) { AbsoluteOffset = new Point(10, 10) }, $"Using LuaCsForBarotrauma revision {AssemblyInfo.GitRevision} version {version}", Color.Red)
{
IgnoreLayoutGroups = false
@@ -703,8 +705,6 @@ namespace Barotrauma
#region Selection
public override void Select()
{
GameMain.LuaCs.Stop();
ResetModUpdateButton();
if (WorkshopItemsToUpdate.Any())
@@ -1314,8 +1314,6 @@ namespace Barotrauma
return;
}
GameMain.LuaCs.CheckInitialize();
selectedSub = new SubmarineInfo(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"));
GameMain.GameSession = new GameSession(selectedSub, Option.None, CampaignDataPath.CreateRegular(savePath), GameModePreset.SinglePlayerCampaign, settings, mapSeed);
@@ -1331,8 +1329,6 @@ namespace Barotrauma
{
if (string.IsNullOrWhiteSpace(path)) return;
GameMain.LuaCs.CheckInitialize();
try
{
CampaignDataPath dataPath =