Rework handling of bk4 constructor

Can't really detect if it's shuffled or not; just assume it's always unshuffled unless it originates from a save file read. Probably not a perfect solution, but achieves better results.

https://projectpokemon.org/home/forums/topic/56217-error-in-archive-bk4/
This commit is contained in:
Kurt 2020-03-18 23:34:53 -07:00
parent 090f83d197
commit 287a2ac5c5
4 changed files with 21 additions and 25 deletions

View file

@ -4,7 +4,10 @@ using System.Collections.Generic;
namespace PKHeX.Core
{
/// <summary> Generation 4 <see cref="PKM"/> format, exclusively for Pokémon Battle Revolution. </summary>
/// <remarks> Values are stored in Big Endian format rather than Little Endian. Beware. </remarks>
/// <remarks>
/// When stored in the save file, these are only shuffled; no xor encryption is performed.
/// Values are stored in Big Endian format rather than Little Endian. Beware.
/// </remarks>
public sealed class BK4 : G4PKM
{
private static readonly ushort[] Unused =
@ -25,26 +28,26 @@ namespace PKHeX.Core
public override byte[] Data { get; }
public static BK4 ReadUnshuffle(byte[] data)
{
var PID = BigEndian.ToUInt32(data, 0);
uint sv = ((PID & 0x3E000) >> 0xD) % 24;
var Data = PokeCrypto.ShuffleArray(data, sv, PokeCrypto.SIZE_4BLOCK);
var result = new BK4(Data);
result.RefreshChecksum();
return result;
}
public BK4(byte[] data)
{
Data = data;
uint sv = ((PID & 0x3E000) >> 0xD) % 24;
Data = PokeCrypto.ShuffleArray(Data, sv, PokeCrypto.SIZE_4BLOCK);
if (Sanity != 0 && Species <= MaxSpeciesID && !ChecksumValid) // We can only hope
RefreshChecksum();
if (Valid && Sanity == 0)
Sanity = 0x4000;
ResetPartyStats();
}
public BK4()
{
Data = new byte[SIZE_PARTY];
Sanity = 0x4000;
ResetPartyStats();
}
public override PKM Clone() => new BK4((byte[])Encrypt().Clone()){Identifier = Identifier};
public BK4() : this(new byte[PokeCrypto.SIZE_4STORED]) { }
public override PKM Clone() => new BK4((byte[])Data.Clone()){Identifier = Identifier};
public string GetString(int Offset, int Count) => StringConverter4.GetBEString4(Data, Offset, Count);
public byte[] SetString(string value, int maxLength) => StringConverter4.SetBEString4(value, maxLength);

View file

@ -124,14 +124,9 @@ namespace PKHeX.Core
_ => new PK3(data)
};
case 4:
var pk = new PK4(data);
if (!pk.Valid || pk.Sanity != 0)
{
var bk = new BK4(data);
if (bk.Valid)
return bk;
}
return pk;
if (BitConverter.ToUInt16(data, 0x06) != 0)
return new BK4(data);
return new PK4(data);
case 5:
return new PK5(data);
case 6:

View file

@ -343,8 +343,6 @@ namespace PKHeX.Core
public static void DecryptIfEncrypted45(ref byte[] pkm)
{
if (BitConverter.ToUInt16(pkm, 4) != 0) // BK4
return;
if (BitConverter.ToUInt32(pkm, 0x64) != 0)
pkm = DecryptArray45(pkm);
}

View file

@ -208,7 +208,7 @@ namespace PKHeX.Core
{
if (data.Length != SIZE_STORED)
Array.Resize(ref data, SIZE_STORED);
return new BK4(data);
return BK4.ReadUnshuffle(data);
}
protected override byte[] DecryptPKM(byte[] data) => data;