From 15ea3014e31f8b924d636a1c8a13d179cca56662 Mon Sep 17 00:00:00 2001 From: Frank Nielson Date: Fri, 16 Oct 2026 21:32:40 -0600 Subject: [PATCH 1/2] Keep downloaded mod archives so other tools can collect them Archives downloaded from Nexus Mods are no longer deleted after installing. They stay in the Nexus folder for mods like ModSyncCheck to move out, and Stardrop deletes any still there once they are a week old. A download whose name is already taken by a kept archive overwrites it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WZe5qavYftiucj2HUFfcDC --- Stardrop/Program.cs | 5 +++-- Stardrop/Utilities/External/NexusClient.cs | 7 ++++--- Stardrop/Views/MainWindow.axaml.cs | 18 +++--------------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/Stardrop/Program.cs b/Stardrop/Program.cs index b02fffe..f2d0b5a 100644 --- a/Stardrop/Program.cs +++ b/Stardrop/Program.cs @@ -147,9 +147,10 @@ public static void Main(string[] args) settings.NexusDetails = new NexusUser(); } - // Delete any files underneath the Nexus folder + // Delete the downloaded archives underneath the Nexus folder once they are a week old. They are kept + // after installing so that mods like ModSyncCheck can collect them, which moves them out of the folder var nexusDirectory = new DirectoryInfo(Pathing.GetNexusPath()); - foreach (FileInfo file in nexusDirectory.GetFiles()) + foreach (FileInfo file in nexusDirectory.GetFiles().Where(f => f.LastWriteTime < DateTime.Now.AddDays(-7))) { file.Delete(); } diff --git a/Stardrop/Utilities/External/NexusClient.cs b/Stardrop/Utilities/External/NexusClient.cs index beffcd3..bc6e1f9 100644 --- a/Stardrop/Utilities/External/NexusClient.cs +++ b/Stardrop/Utilities/External/NexusClient.cs @@ -470,8 +470,9 @@ public async Task DownloadFileAndGetPath(string uri, string // usable as a filename is on the way into the path rather than at any one of them var filePath = Path.Combine(Pathing.GetNexusPath(), Pathing.GetSafePathSegment(fileName)); - // FileMode.CreateNew throws on a name that is already taken, which would otherwise send a download that - // never started down the cleanup path below and delete whatever already held the name + // Archives are kept after installing, so an archive from an earlier download can already hold the name. + // It is overwritten via FileMode.Create, and only once the response has succeeded, so a download that + // never started leaves the earlier archive alone bool hasCreatedFile = false; try { @@ -483,7 +484,7 @@ public async Task DownloadFileAndGetPath(string uri, string return new(DownloadResultKind.Failed, null); } - using var fileStream = new FileStream(filePath, FileMode.CreateNew); + using var fileStream = new FileStream(filePath, FileMode.Create); hasCreatedFile = true; using var downloadStream = await response.Content.ReadAsStreamAsync(); diff --git a/Stardrop/Views/MainWindow.axaml.cs b/Stardrop/Views/MainWindow.axaml.cs index 55f6592..d7e3d51 100644 --- a/Stardrop/Views/MainWindow.axaml.cs +++ b/Stardrop/Views/MainWindow.axaml.cs @@ -1161,11 +1161,7 @@ private async void InstallButton_Click(object? sender, Avalonia.Interactivity.Ro await CheckForModUpdates(addedMods, useCache: true, skipCacheCheck: true); await GetCachedModUpdates(_viewModel.Mods.ToList(), skipCacheCheck: true); - // Delete the downloaded archived mod - if (File.Exists(downloadedFilePath)) - { - File.Delete(downloadedFilePath); - } + // The downloaded archive is kept in the Nexus folder rather than deleted _viewModel.EvaluateRequirements(); _viewModel.UpdateEndorsements(); @@ -2089,11 +2085,7 @@ private async Task HandleBulkModInstall(bool enabledModsOnly = false) await CheckForModUpdates(addedMods, useCache: true, skipCacheCheck: true); await GetCachedModUpdates(_viewModel.Mods.ToList(), skipCacheCheck: true); - // Delete the downloaded archived mods - foreach (var filePath in updateFilePaths.Where(p => File.Exists(p))) - { - File.Delete(filePath); - } + // The downloaded archives are kept in the Nexus folder rather than deleted _viewModel.EvaluateRequirements(); _viewModel.UpdateEndorsements(); @@ -2271,11 +2263,7 @@ internal async Task ProcessNXMLink(NXM nxmLink) await CheckForModUpdates(addedMods, useCache: true, skipCacheCheck: true); await GetCachedModUpdates(_viewModel.Mods.ToList(), skipCacheCheck: true); - // Delete the downloaded archived mod - if (File.Exists(downloadedFilePath)) - { - File.Delete(downloadedFilePath); - } + // The downloaded archive is kept in the Nexus folder rather than deleted _viewModel.EvaluateRequirements(); _viewModel.UpdateEndorsements(); From 54fe4598ccf3169432fe46f2ea049a652de1e473 Mon Sep 17 00:00:00 2001 From: Frank Nielson Date: Fri, 16 Oct 2026 22:34:13 -0600 Subject: [PATCH 2/2] Reword the comments on kept archives Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WZe5qavYftiucj2HUFfcDC --- Stardrop/Views/MainWindow.axaml.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Stardrop/Views/MainWindow.axaml.cs b/Stardrop/Views/MainWindow.axaml.cs index d7e3d51..4517425 100644 --- a/Stardrop/Views/MainWindow.axaml.cs +++ b/Stardrop/Views/MainWindow.axaml.cs @@ -1161,7 +1161,7 @@ private async void InstallButton_Click(object? sender, Avalonia.Interactivity.Ro await CheckForModUpdates(addedMods, useCache: true, skipCacheCheck: true); await GetCachedModUpdates(_viewModel.Mods.ToList(), skipCacheCheck: true); - // The downloaded archive is kept in the Nexus folder rather than deleted + // The downloaded archive is kept in the Nexus folder to be deleted later _viewModel.EvaluateRequirements(); _viewModel.UpdateEndorsements(); @@ -2085,7 +2085,7 @@ private async Task HandleBulkModInstall(bool enabledModsOnly = false) await CheckForModUpdates(addedMods, useCache: true, skipCacheCheck: true); await GetCachedModUpdates(_viewModel.Mods.ToList(), skipCacheCheck: true); - // The downloaded archives are kept in the Nexus folder rather than deleted + // The downloaded archives are kept in the Nexus folder to be deleted later _viewModel.EvaluateRequirements(); _viewModel.UpdateEndorsements(); @@ -2263,7 +2263,7 @@ internal async Task ProcessNXMLink(NXM nxmLink) await CheckForModUpdates(addedMods, useCache: true, skipCacheCheck: true); await GetCachedModUpdates(_viewModel.Mods.ToList(), skipCacheCheck: true); - // The downloaded archive is kept in the Nexus folder rather than deleted + // The downloaded archive is kept in the Nexus folder to be deleted later _viewModel.EvaluateRequirements(); _viewModel.UpdateEndorsements();