diff --git a/src/Core/API/Config.cs b/src/Core/API/Config.cs index 1d38eb0..98fd668 100644 --- a/src/Core/API/Config.cs +++ b/src/Core/API/Config.cs @@ -40,4 +40,5 @@ public class ModInstallConfig : ModInstaller.IConfig public IEnumerable DirsAtRoot { get; set; } = Array.Empty(); public IEnumerable ExcludedFromInstall { get; set; } = Array.Empty(); public IEnumerable ExcludedFromConfig { get; set; } = Array.Empty(); + public bool GenerateModDetails { get; set; } = true; } diff --git a/src/Core/Mods/Installation/Installers/ModInstaller.cs b/src/Core/Mods/Installation/Installers/ModInstaller.cs index a1c64bc..615bf09 100644 --- a/src/Core/Mods/Installation/Installers/ModInstaller.cs +++ b/src/Core/Mods/Installation/Installers/ModInstaller.cs @@ -1,5 +1,4 @@ using Core.Games; -using Core.Packages.Installation.Backup; using Core.Packages.Installation.Installers; using Core.Utils; using Microsoft.Extensions.FileSystemGlobbing; @@ -17,14 +16,21 @@ IEnumerable ExcludedFromConfig { get; } + + bool GenerateModDetails + { + get; + } } private readonly Matcher filesToConfigureMatcher; + private readonly bool generateModDetails; internal ModInstaller(IInstaller inner, IGame game, ITempDir tempDir, IConfig config) : base(inner, game, tempDir, config) { filesToConfigureMatcher = Matchers.ExcludingPatterns(config.ExcludedFromConfig); + generateModDetails = config.GenerateModDetails; } protected override void Install(Action innerInstall) @@ -65,6 +71,10 @@ private void WriteModConfigFiles(ConfigEntries modConfig) AddToInstalledFiles(PostProcessor.AppendCrdFileEntries(modConfigDirPath, modConfig.CrdFileEntries)); AddToInstalledFiles(PostProcessor.AppendTrdFileEntries(modConfigDirPath, modConfig.TrdFileEntries)); AddToInstalledFiles(PostProcessor.AppendDrivelineRecords(modConfigDirPath, modConfig.DrivelineRecords)); + if (generateModDetails && (modConfig.CrdFileEntries.Any() || modConfig.DrivelineRecords.Any())) + { + AddToInstalledFiles(PostProcessor.GenerateModDetails(modConfigDirPath, Inner)); + } } private List CrdFileEntries() => diff --git a/src/Core/Mods/Installation/Installers/PostProcessor.cs b/src/Core/Mods/Installation/Installers/PostProcessor.cs index 50f7070..9a22fe9 100644 --- a/src/Core/Mods/Installation/Installers/PostProcessor.cs +++ b/src/Core/Mods/Installation/Installers/PostProcessor.cs @@ -1,4 +1,5 @@ -using Core.Utils; +using Core.Packages.Installation; +using Core.Utils; namespace Core.Mods.Installation.Installers; @@ -108,4 +109,26 @@ private static string DrivelineFileContents(RootedPath driveLineFilePath, string } private static string IdentityProcessor(string block) => block; + + public static RootedPath GenerateModDetails(RootedPath destDirPath, IInstallation installation) + { + var modName = Path.GetFileName(destDirPath.Full); + var filePath = destDirPath.SubPath($"{modName}.xml"); + var contents = @$" + + + + + + + + + + + + +"; + File.WriteAllText(filePath.Full, contents); + return filePath; + } } diff --git a/tests/Core.Tests/API/ModManagerIntegrationTest.cs b/tests/Core.Tests/API/ModManagerIntegrationTest.cs index 00cd95d..c9e4b7a 100644 --- a/tests/Core.Tests/API/ModManagerIntegrationTest.cs +++ b/tests/Core.Tests/API/ModManagerIntegrationTest.cs @@ -449,7 +449,7 @@ public void Install_PerformsBackups() } [Fact] - public void Install_OldVehiclesRequireBootfiles() + public void Install_OldVehiclesDoNotRequireBootfiles() { var drivelineRecord = $"RECORD foo"; modRepositoryMock.Setup(_ => _.ListEnabled()).Returns([ @@ -463,9 +463,14 @@ public void Install_OldVehiclesRequireBootfiles() modManager.InstallEnabledMods(eventHandlerMock.Object); - persistedState.Should().HaveInstalled(["Package100", "__bootfiles900"]); - File.ReadAllText(GamePath(VehicleListRelativePath).Full).Should().Contain("Vehicle.crd"); - File.ReadAllText(GamePath(DrivelineRelativePath).Full).Should().Contain(drivelineRecord); + persistedState.Should().HaveInstalled(["Package100"]); + var generatedConfigDir = $"Package100_{100:x}"; + File.ReadAllText(GamePath(PostProcessor.GameSupportedModDirectory, generatedConfigDir, + PostProcessor.VehicleListFileName).Full).Should().Contain("Vehicle.crd"); + File.ReadAllText(GamePath(PostProcessor.GameSupportedModDirectory, generatedConfigDir, + PostProcessor.DrivelineFileName).Full).Should().Contain(drivelineRecord); + File.Exists(GamePath(PostProcessor.GameSupportedModDirectory, generatedConfigDir, $"{generatedConfigDir}.xml") + .Full).Should().BeTrue(); } [Fact] @@ -495,6 +500,12 @@ public void Install_AllTracksRequireBootfiles() modManager.InstallEnabledMods(eventHandlerMock.Object); persistedState.Should().HaveInstalled(["Package100", "__bootfiles900"]); + var generatedConfigDir = $"Package100_{100:x}"; + File.ReadAllText(GamePath(PostProcessor.GameSupportedModDirectory, generatedConfigDir, + PostProcessor.TrackListFileName).Full).Should().Contain("Track.trd"); + File.Exists(GamePath(PostProcessor.GameSupportedModDirectory, generatedConfigDir, $"{generatedConfigDir}.xml") + .Full).Should().BeFalse(); + File.ReadAllText(GamePath(TrackListRelativePath).Full).Should().Contain("Track.trd"); } @@ -502,7 +513,7 @@ public void Install_AllTracksRequireBootfiles() public void Install_ExtractsBootfilesFromGameByDefault() { modRepositoryMock.Setup(_ => _.ListEnabled()).Returns([ - CreateModArchive(100, [Path.Combine(DirAtRoot, "Foo.crd")]) + CreateModArchive(100, [Path.Combine(DirAtRoot, "Foo.trd")]) ]); // Unfortunately, there is no easy way to create pak files! @@ -520,7 +531,7 @@ public void Install_ExtractsBootfilesFromGameByDefault() public void Install_ChoosesLastOfMultipleCustomBootfiles() { modRepositoryMock.Setup(_ => _.ListEnabled()).Returns([ - CreateModArchive(100, [Path.Combine(DirAtRoot, "Foo.crd")]), + CreateModArchive(100, [Path.Combine(DirAtRoot, "Foo.trd")]), CreateCustomBootfiles(900), CreateCustomBootfiles(901) ]);