fix apk loading issues (#913)

* fix apk loading issues

Someone contacted me some days ago and notified me that some problems showed up with my APK loading implementation.
Namely:

file reference registration (importFilesHash) was missing
split files weren't handled
external resource files weren't registered
This pr fixes those problems.

* revert weird changes

* fix missing }

* fix formatting

* use entry.FullName for the basePath instead of entry.Name
This commit is contained in:
Rudolf Kolbe 2022-02-15 04:19:50 +01:00 committed by GitHub
parent 8d193a63cd
commit e7a4604a65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
@ -245,6 +245,56 @@ namespace AssetStudio
{
using (ZipArchive archive = new ZipArchive(reader.BaseStream, ZipArchiveMode.Read))
{
List<string> splitFiles = new List<string>();
// register all files before parsing the assets so that the external references can be found
// and find split files
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.Name.Contains(".split"))
{
string baseName = Path.GetFileNameWithoutExtension(entry.Name);
string basePath = Path.Combine(Path.GetDirectoryName(entry.FullName), baseName);
if (!splitFiles.Contains(basePath))
{
splitFiles.Add(basePath);
importFilesHash.Add(baseName);
}
}
else
{
importFilesHash.Add(entry.Name);
}
}
// merge split files and load the result
foreach (string basePath in splitFiles)
{
try
{
Stream splitStream = new MemoryStream();
int i = 0;
while (true)
{
string path = $"{basePath}.split{i++}";
ZipArchiveEntry entry = archive.GetEntry(path);
if (entry == null)
break;
using (Stream entryStream = entry.Open())
{
entryStream.CopyTo(splitStream);
}
}
splitStream.Seek(0, SeekOrigin.Begin);
FileReader entryReader = new FileReader(basePath, splitStream);
LoadFile(entryReader);
}
catch (Exception e)
{
Logger.Error($"Error while reading zip split file {basePath}", e);
}
}
// load all entries
foreach (ZipArchiveEntry entry in archive.Entries)
{
try
@ -262,6 +312,14 @@ namespace AssetStudio
FileReader entryReader = new FileReader(dummyPath, streamReader);
LoadFile(entryReader);
if (entryReader.FileType == FileType.ResourceFile)
{
entryReader.Position = 0;
if (!resourceFileReaders.ContainsKey(entry.Name))
{
resourceFileReaders.Add(entry.Name, entryReader);
}
}
}
catch (Exception e)
{
@ -493,4 +551,4 @@ namespace AssetStudio
}
}
}
}
}