From d3cc5b0b58646996ad5b3a183e8b8280614d3df3 Mon Sep 17 00:00:00 2001 From: Exter-N Date: Tue, 27 Jan 2026 04:44:42 +0100 Subject: [PATCH] Fix SharpCompress reading regression --- Penumbra/Import/TexToolsImporter.Archives.cs | 19 ++++++------- Penumbra/Services/MigrationManager.cs | 11 +++---- Penumbra/Util/ArchiveUtility.cs | 30 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Penumbra/Import/TexToolsImporter.Archives.cs b/Penumbra/Import/TexToolsImporter.Archives.cs index 21e9e6d1..b2425168 100644 --- a/Penumbra/Import/TexToolsImporter.Archives.cs +++ b/Penumbra/Import/TexToolsImporter.Archives.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Penumbra.Import.Structs; using Penumbra.Mods; +using Penumbra.Util; using SharpCompress.Archives; using SharpCompress.Archives.Rar; using SharpCompress.Archives.SevenZip; @@ -55,16 +56,14 @@ public partial class TexToolsImporter State = ImporterState.ExtractingModFiles; _currentFileIdx = 0; - var reader = archive.ExtractAllEntries(); - - while (reader.MoveToNextEntry()) + ArchiveUtility.ForEachEntry(archive, reader => { _token.ThrowIfCancellationRequested(); if (reader.Entry.IsDirectory) { --_currentNumFiles; - continue; + return; } Penumbra.Log.Information($" -> Extracting {reader.Entry.Key}"); @@ -92,7 +91,7 @@ public partial class TexToolsImporter } ++_currentFileIdx; - } + }); _token.ThrowIfCancellationRequested(); var oldName = _currentModDirectory.FullName; @@ -136,21 +135,21 @@ public partial class TexToolsImporter } - private void HandleFileMigrationsAndWrite(IReader reader) + private void HandleFileMigrationsAndWrite(ArchiveUtility.ReaderShim reader) { switch (Path.GetExtension(reader.Entry.Key)) { case ".mdl": - _migrationManager.MigrateMdlDuringExtraction(reader, _currentModDirectory!.FullName, ExtractionOptions); + _migrationManager.MigrateMdlDuringExtraction(reader, _currentModDirectory!.FullName); break; case ".mtrl": - _migrationManager.MigrateMtrlDuringExtraction(reader, _currentModDirectory!.FullName, ExtractionOptions); + _migrationManager.MigrateMtrlDuringExtraction(reader, _currentModDirectory!.FullName); break; case ".tex": - _migrationManager.FixMipMaps(reader, _currentModDirectory!.FullName, ExtractionOptions); + _migrationManager.FixMipMaps(reader, _currentModDirectory!.FullName); break; default: - reader.WriteEntryToDirectory(_currentModDirectory!.FullName, ExtractionOptions); + reader.WriteEntryToDirectory(_currentModDirectory!.FullName); break; } } diff --git a/Penumbra/Services/MigrationManager.cs b/Penumbra/Services/MigrationManager.cs index dbfd23c7..1de0981f 100644 --- a/Penumbra/Services/MigrationManager.cs +++ b/Penumbra/Services/MigrationManager.cs @@ -4,6 +4,7 @@ using Lumina.Extensions; using Luna; using Penumbra.GameData.Files.Utility; using Penumbra.Import.Textures; +using Penumbra.Util; using SharpCompress.Common; using SharpCompress.Readers; using MdlFile = Penumbra.GameData.Files.MdlFile; @@ -238,11 +239,11 @@ public class MigrationManager(Configuration config) : IService } /// Writes or migrates a .mdl file during extraction from a regular archive. - public void MigrateMdlDuringExtraction(IReader reader, string directory, ExtractionOptions options) + public void MigrateMdlDuringExtraction(ArchiveUtility.ReaderShim reader, string directory) { if (!config.MigrateImportedModelsToV6) { - reader.WriteEntryToDirectory(directory, options); + reader.WriteEntryToDirectory(directory); return; } @@ -270,11 +271,11 @@ public class MigrationManager(Configuration config) : IService } } - public void MigrateMtrlDuringExtraction(IReader reader, string directory, ExtractionOptions options) + public void MigrateMtrlDuringExtraction(ArchiveUtility.ReaderShim reader, string directory) { if (!config.MigrateImportedMaterialsToLegacy || true) // TODO change when this is working { - reader.WriteEntryToDirectory(directory, options); + reader.WriteEntryToDirectory(directory); return; } @@ -299,7 +300,7 @@ public class MigrationManager(Configuration config) : IService } } - public void FixMipMaps(IReader reader, string directory, ExtractionOptions options) + public void FixMipMaps(ArchiveUtility.ReaderShim reader, string directory) { var path = Path.Combine(directory, reader.Entry.Key!); using var s = new MemoryStream(); diff --git a/Penumbra/Util/ArchiveUtility.cs b/Penumbra/Util/ArchiveUtility.cs index 691ebd23..5397bdf4 100644 --- a/Penumbra/Util/ArchiveUtility.cs +++ b/Penumbra/Util/ArchiveUtility.cs @@ -1,5 +1,6 @@ using SharpCompress.Archives; using SharpCompress.Common; +using SharpCompress.Readers; namespace Penumbra.Util; @@ -26,4 +27,33 @@ public static class ArchiveUtility Directory.CreateDirectory(directoryPath); ArchiveFactory.WriteToDirectory(filePath, directoryPath, ExtractionOptions); } + + public static void ForEachEntry(IArchive archive, Action action) + { + if (archive.IsSolid || archive.Type is ArchiveType.SevenZip) + { + var reader = archive.ExtractAllEntries(); + + while (reader.MoveToNextEntry()) + action(new(reader.Entry, reader.OpenEntryStream)); + } + else + { + foreach (var entry in archive.Entries) + action(new(entry, entry.OpenEntryStream)); + } + } + + /// This shim imitates the parts of that are used throughout the importers. + public readonly record struct ReaderShim(IEntry Entry, Func OpenEntryStream) + { + public void WriteEntryToDirectory(string directory) + { + var path = Path.Combine(directory, Entry.Key!); + Directory.CreateDirectory(Path.GetDirectoryName(path)!); + using var e = OpenEntryStream(); + using var f = File.Open(path, FileMode.Create, FileAccess.Write); + e.CopyTo(f); + } + } }