mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-08 19:17:05 -05:00
Deduplicate some logic
No need to length check in the SwishCrypto hash check, as the methods pre-check length as well. Extract checksum footer check for Gen5 saves
This commit is contained in:
@@ -203,6 +203,10 @@ public static SCBlock ReadFromOffset(ReadOnlySpan<byte> data, ref int offset)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges the properties from <see cref="other"/> into this object.
|
||||
/// </summary>
|
||||
/// <param name="other">Block to copy all values from.</param>
|
||||
public void CopyFrom(SCBlock other)
|
||||
{
|
||||
if (Type.IsBoolean())
|
||||
|
||||
@@ -82,24 +82,6 @@ private static byte[] ComputeHash(byte[] data)
|
||||
/// <returns>True if hash matches</returns>
|
||||
public static bool GetIsHashValid(byte[] data)
|
||||
{
|
||||
if (!SaveUtil.SizesSWSH.Contains(data.Length))
|
||||
return false;
|
||||
|
||||
var hash = ComputeHash(data);
|
||||
var span = data.AsSpan()[^hash.Length..];
|
||||
return span.SequenceEqual(hash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the file is a rough example of a save file.
|
||||
/// </summary>
|
||||
/// <param name="data">Encrypted save data</param>
|
||||
/// <returns>True if hash matches</returns>
|
||||
public static bool GetIsHashValidLA(byte[] data)
|
||||
{
|
||||
if (data.Length is not (SaveUtil.SIZE_G8LA or SaveUtil.SIZE_G8LA_1))
|
||||
return false;
|
||||
|
||||
var hash = ComputeHash(data);
|
||||
var span = data.AsSpan()[^hash.Length..];
|
||||
return span.SequenceEqual(hash);
|
||||
|
||||
@@ -428,16 +428,20 @@ private static GameVersion GetIsG5SAV(ReadOnlySpan<byte> data)
|
||||
if (data.Length != SIZE_G5RAW)
|
||||
return Invalid;
|
||||
|
||||
// check the checksum block validity; nobody would normally modify this region
|
||||
ushort chk1 = ReadUInt16LittleEndian(data[(SIZE_G5BW - 0x100 + 0x8C + 0xE)..]);
|
||||
ushort actual1 = Checksums.CRC16_CCITT(data.Slice(SIZE_G5BW - 0x100, 0x8C));
|
||||
if (chk1 == actual1)
|
||||
// check the checksum footer block validity; nobody would normally modify this region
|
||||
if (IsValidFooter(data, SIZE_G5BW, 0x8C))
|
||||
return BW;
|
||||
ushort chk2 = ReadUInt16LittleEndian(data[(SIZE_G5B2W2 - 0x100 + 0x94 + 0xE)..]);
|
||||
ushort actual2 = Checksums.CRC16_CCITT(data.Slice(SIZE_G5B2W2 - 0x100, 0x94));
|
||||
if (chk2 == actual2)
|
||||
if (IsValidFooter(data, SIZE_G5B2W2, 0x94))
|
||||
return B2W2;
|
||||
return Invalid;
|
||||
|
||||
static bool IsValidFooter(ReadOnlySpan<byte> data, int mainSize, int infoLength)
|
||||
{
|
||||
var footer = data.Slice(mainSize - 0x100, infoLength + 0x10);
|
||||
ushort stored = ReadUInt16LittleEndian(footer[^2..]);
|
||||
ushort actual = Checksums.CRC16_CCITT(footer[..infoLength]);
|
||||
return stored == actual;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Checks to see if the data belongs to a Gen6 save</summary>
|
||||
@@ -514,7 +518,7 @@ private static GameVersion GetIsG8SAV_LA(byte[] data)
|
||||
if (data.Length is not (SIZE_G8LA or SIZE_G8LA_1))
|
||||
return Invalid;
|
||||
|
||||
return SwishCrypto.GetIsHashValidLA(data) ? PLA : Invalid;
|
||||
return SwishCrypto.GetIsHashValid(data) ? PLA : Invalid;
|
||||
}
|
||||
|
||||
private static bool GetIsBank7(ReadOnlySpan<byte> data) => data.Length == SIZE_G7BANK && data[0] != 0;
|
||||
|
||||
Reference in New Issue
Block a user