Fix SharpCompress reading regression

This commit is contained in:
Exter-N 2026-01-27 04:44:42 +01:00 committed by Ottermandias
parent 753876cb9b
commit d3cc5b0b58
3 changed files with 45 additions and 15 deletions

View file

@ -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;
}
}

View file

@ -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
}
/// <summary> Writes or migrates a .mdl file during extraction from a regular archive. </summary>
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();

View file

@ -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<ReaderShim> 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));
}
}
/// <summary> This shim imitates the parts of <see cref="IReader"/> that are used throughout the importers. </summary>
public readonly record struct ReaderShim(IEntry Entry, Func<Stream> 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);
}
}
}