i hope this breaks nothing

This commit is contained in:
iAmAsval
2020-07-25 20:54:30 +02:00
parent a114956d84
commit 947002cd00
5 changed files with 36 additions and 28 deletions

View File

@@ -24,7 +24,7 @@ namespace FModel
});
public static bool bSearch = false; // trigger the event to select a file thank to the search window
public static string sSearch = string.Empty; // this will be the file name triggered
public static FGame Game = new FGame(EGame.Unknown, EPakVersion.LATEST);
public static FGame Game = new FGame(EGame.Unknown, EPakVersion.LATEST, 0);
public const EFModel Build =
#if RELEASE
EFModel.Release;
@@ -39,11 +39,13 @@ namespace FModel
{
public EGame ActualGame;
public EPakVersion Version;
public int SubVersion;
public FGame(EGame game, EPakVersion version)
public FGame(EGame game, EPakVersion version, int subVersion)
{
ActualGame = game;
Version = version;
SubVersion = subVersion;
}
public string GetName()

View File

@@ -46,8 +46,12 @@ namespace FModel.Grabber.Paks
if (!Utils.Paks.IsFileReadLocked(new FileInfo(paks[i])))
{
PakFileReader pakFile = new PakFileReader(paks[i]);
if (i == 0) Globals.Game.Version = pakFile.Info.Version;
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Registering]", $"{pakFile.FileName} with GUID {pakFile.Info.EncryptionKeyGuid.Hex}");
if (i == 0)
{
Globals.Game.Version = pakFile.Info.Version;
Globals.Game.SubVersion = pakFile.Info.SubVersion;
}
Application.Current.Dispatcher.Invoke(delegate
{

View File

@@ -71,7 +71,7 @@ namespace PakReader.Parsers.Objects
else
CompressionMethodIndex = reader.ReadUInt32();
}
if (Version <= EPakVersion.INITIAL) reader.ReadInt64(); // Timestamp
if (Version < EPakVersion.NO_TIMESTAMPS) reader.ReadInt64(); // Timestamp
reader.ReadBytes(20); // Hash
if (Version >= EPakVersion.COMPRESSION_ENCRYPTION)
{

View File

@@ -20,29 +20,29 @@ namespace PakReader.Parsers.Objects
public readonly string[] CompressionMethods; // 160 bytes
// 221 bytes total
internal const long SERIALIZED_SIZE = 4 * 2 + 8 * 2 + 20 + /* new fields */ 1 + 16;
internal const long _SIZE = 4 * 2 + 8 * 2 + 20 + 1 + 16;
internal const long _SIZE8 = _SIZE + 4 * 32;
internal const long _SIZE8A = _SIZE8 + 32;
internal const long _SIZE9 = _SIZE8A + 1;
internal FPakInfo ReadPakInfo(BinaryReader reader)
{
long offset = reader.BaseStream.Length - SERIALIZED_SIZE;
long terminator = offset - 300;
int maxNumCompressionMethods = 0;
while (offset > terminator)
long fileSize = reader.BaseStream.Length;
long[] OffsetsToTry = new long[4] { _SIZE, _SIZE8, _SIZE8A, _SIZE9 };
for (int i = 0; i < OffsetsToTry.Length; i++)
{
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
FPakInfo info = new FPakInfo(reader, maxNumCompressionMethods);
if (info.Version != EPakVersion.INVALID)
return info;
else
if (fileSize - OffsetsToTry[i] > 0)
{
offset -= COMPRESSION_METHOD_NAME_LEN;
maxNumCompressionMethods++;
reader.BaseStream.Seek(fileSize - OffsetsToTry[i], SeekOrigin.Begin);
FPakInfo info = new FPakInfo(reader, OffsetsToTry[i]);
if (info.Version != EPakVersion.INVALID)
return info;
}
}
return default;
}
internal FPakInfo(BinaryReader reader, int maxNumCompressionMethods)
internal FPakInfo(BinaryReader reader, long offset)
{
// Serialize if version is at least EPakVersion.ENCRYPTION_KEY_GUID
EncryptionKeyGuid = new FGuid(reader);
@@ -62,15 +62,12 @@ namespace PakReader.Parsers.Objects
}
Version = (EPakVersion)reader.ReadInt32();
int b;
if (maxNumCompressionMethods == 5 && Version == EPakVersion.FNAME_BASED_COMPRESSION_METHOD) // UE4.23
b = (((int)Version) << 4) | (1);
else
b = (((int)Version) << 4) | (0);
SubVersion = b & 15;
SubVersion = (offset == _SIZE8A && Version == EPakVersion.FNAME_BASED_COMPRESSION_METHOD) ? 1 : 0;
IndexOffset = reader.ReadInt64();
IndexSize = reader.ReadInt64();
IndexHash = new FSHAHash(reader);
if (Version == EPakVersion.FROZEN_INDEX)
reader.ReadByte(); // bIndexIsFrozen
if (Version < EPakVersion.FNAME_BASED_COMPRESSION_METHOD)
{
@@ -78,10 +75,10 @@ namespace PakReader.Parsers.Objects
}
else
{
int BufferSize = COMPRESSION_METHOD_NAME_LEN * maxNumCompressionMethods;
int BufferSize = COMPRESSION_METHOD_NAME_LEN * 4;
byte[] Methods = reader.ReadBytes(BufferSize);
var MethodList = new List<string>(maxNumCompressionMethods);
for (int i = 0; i < maxNumCompressionMethods; i++)
var MethodList = new List<string>(4);
for (int i = 0; i < 4; i++)
{
if (Methods[i*COMPRESSION_METHOD_NAME_LEN] != 0)
{
@@ -90,6 +87,11 @@ namespace PakReader.Parsers.Objects
}
CompressionMethods = MethodList.ToArray();
}
if (Version < EPakVersion.INDEX_ENCRYPTION)
bEncryptedIndex = false;
if (Version < EPakVersion.ENCRYPTION_KEY_GUID)
EncryptionKeyGuid = new FGuid(0u, 0u, 0u, 0u);
}
}
}

View File

@@ -22,8 +22,8 @@ namespace PakReader.Parsers.Objects
FirstMipToSerialize = 0; // what: https://github.com/EpicGames/UnrealEngine/blob/4.24/Engine/Source/Runtime/Engine/Private/TextureDerivedData.cpp#L1316
Mips = reader.ReadTArray(() => new FTexture2DMipMap(reader, ubulk, bulkOffset));
if (FModel.Globals.Game.ActualGame == FModel.EGame.Valorant || FModel.Globals.Game.Version > EPakVersion.FNAME_BASED_COMPRESSION_METHOD)
if (FModel.Globals.Game.Version > EPakVersion.FNAME_BASED_COMPRESSION_METHOD || FModel.Globals.Game.SubVersion == 1)
{
if (reader.ReadInt32() != 0) throw new FileLoadException("VirtualTextures are not supported");
}