diff --git a/WheelWizard/Features/CustomDistributions/IDistribution.cs b/WheelWizard/Features/CustomDistributions/IDistribution.cs index 51f6e2fd..d2398c78 100644 --- a/WheelWizard/Features/CustomDistributions/IDistribution.cs +++ b/WheelWizard/Features/CustomDistributions/IDistribution.cs @@ -18,6 +18,16 @@ public interface IDistribution /// string FolderName { get; } + /// + /// The name of the wiiDisc .xml file in XMLFolderName + /// + string XMLFileName { get; } + + /// + /// The name of the folder containing the distributions wiiDisc .xml file + /// + string XMLFolderName { get; } + /// /// Install the distribution. /// diff --git a/WheelWizard/Features/CustomDistributions/RetroRewind.cs b/WheelWizard/Features/CustomDistributions/RetroRewind.cs index 9c71fc25..1eeb73f1 100644 --- a/WheelWizard/Features/CustomDistributions/RetroRewind.cs +++ b/WheelWizard/Features/CustomDistributions/RetroRewind.cs @@ -29,6 +29,8 @@ public RetroRewind(IFileSystem fileSystem, IApiCaller api) // Keep in mind, whenever we download update files from the server, they are actually 1 folder higher, so it contains this folder. public string FolderName => "RetroRewind6"; + public string XMLFolderName => "riivolution"; + public string XMLFileName => "RetroRewind6"; public async Task InstallAsync(ProgressWindow progressWindow) { @@ -68,9 +70,17 @@ private async Task DownloadAndExtractRetroRewind(ProgressWindow var tempZipPath = PathManager.RetroRewindTempFile; // where we'll do the extraction var tempExtractionPath = PathManager.TempModsFolderPath; - // where the final RR folder should live - var finalDestination = _fileSystem.Path.Combine(PathManager.RiivolutionWhWzFolderPath, FolderName); + //where all distributions are stored + var destinationParentDir = _fileSystem.DirectoryInfo.New(PathManager.RiivolutionWhWzFolderPath); + + //where the RR distribution lives + var distributionDataDestination = _fileSystem.Path.Combine(destinationParentDir.FullName, FolderName); + //where the RR wiiDisc xml file lives + var riivolutionFolderDestination = PathManager.RiivolutionXmlFolderPath; + var riivolutionDiscXMLFile = _fileSystem.Path.Combine(riivolutionFolderDestination, $"{XMLFileName}.xml"); + + Exception? exception = null; try { // 1) Download @@ -101,11 +111,38 @@ private async Task DownloadAndExtractRetroRewind(ProgressWindow } // 4) Replace existing install, if any - if (_fileSystem.Directory.Exists(finalDestination)) - _fileSystem.Directory.Delete(finalDestination, recursive: true); - - // 5) Move into place - _fileSystem.Directory.Move(sourceFolder, finalDestination); + if (_fileSystem.Directory.Exists(distributionDataDestination)) + _fileSystem.Directory.Delete(distributionDataDestination, recursive: true); + if (_fileSystem.File.Exists(riivolutionDiscXMLFile)) + _fileSystem.File.Delete(riivolutionDiscXMLFile); + + // 5) Make sure the target directory exists + var parentDirectory = _fileSystem.DirectoryInfo.New(distributionDataDestination).Parent; + parentDirectory?.Create(); + if ((!parentDirectory?.Exists) ?? true) + throw new DirectoryNotFoundException($"Could not find destination `{parentDirectory?.FullName}`"); + + // 5) Move over distribution data + _fileSystem.Directory.Move(sourceFolder, distributionDataDestination); + + // 6) Move over 'riivolution/' folder. skip existing files + var xmlFolderSource = _fileSystem.Path.Combine(tempExtractionPath, XMLFolderName); + foreach (var file in _fileSystem.Directory.EnumerateFiles(xmlFolderSource, "*", SearchOption.AllDirectories)) + { + var destinationPath = _fileSystem.Path.Combine(riivolutionFolderDestination, _fileSystem.Path.GetRelativePath(xmlFolderSource, file)); + var destinationDirectoryName = _fileSystem.Path.GetDirectoryName(destinationPath); + if (destinationDirectoryName != null) + { + var directory = _fileSystem.DirectoryInfo.New(destinationDirectoryName); + if (!directory?.Exists ?? false) + directory?.Create(); + } + _fileSystem.File.Move(file, destinationPath, false); + } + } + catch (Exception e) + { + exception = e; } finally { @@ -115,7 +152,7 @@ private async Task DownloadAndExtractRetroRewind(ProgressWindow if (_fileSystem.Directory.Exists(tempExtractionPath)) _fileSystem.Directory.Delete(tempExtractionPath, recursive: true); } - return Ok(); + return exception is null ? Ok() : Fail(exception); } private async Task BackupOldrksys() diff --git a/WheelWizard/Services/Launcher/RrLauncher.cs b/WheelWizard/Services/Launcher/RrLauncher.cs index 3809ed02..4475325a 100644 --- a/WheelWizard/Services/Launcher/RrLauncher.cs +++ b/WheelWizard/Services/Launcher/RrLauncher.cs @@ -66,8 +66,16 @@ public async Task Install() { var progressWindow = new ProgressWindow(); progressWindow.Show(); - await CustomDistributionSingletonService.RetroRewind.InstallAsync(progressWindow); + var installResult = await CustomDistributionSingletonService.RetroRewind.InstallAsync(progressWindow); progressWindow.Close(); + if (installResult.IsFailure) + { + await new MessageBoxWindow() + .SetMessageType(MessageBoxWindow.MessageType.Error) + .SetTitleText("Unable to install RetroRewind") + .SetInfoText(installResult.Error.Message) + .ShowDialog(); + } } public async Task Update() diff --git a/WheelWizard/Services/PathManager.cs b/WheelWizard/Services/PathManager.cs index 251952c9..26f3fe9b 100644 --- a/WheelWizard/Services/PathManager.cs +++ b/WheelWizard/Services/PathManager.cs @@ -53,7 +53,8 @@ public static class PathManager // This is not the folder your save file is located in, but its the folder where every Region folder is, so the save file is in SaveFolderPath/Region public static string SaveFolderPath => Path.Combine(RiivolutionWhWzFolderPath, "riivolution", "save", "RetroWFC"); - public static string XmlFilePath => Path.Combine(RiivolutionWhWzFolderPath, "riivolution", "RetroRewind6.xml"); + public static string RiivolutionXmlFolderPath => Path.Combine(RiivolutionWhWzFolderPath, "riivolution"); + public static string XmlFilePath => Path.Combine(RiivolutionXmlFolderPath, "RetroRewind6.xml"); private static string PortableUserFolderPath => Path.Combine(GetDolphinExeDirectory(), RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "user" : "User");