mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 12:33:06 +00:00
small optimizations
Add ccitt method to checksum an existing array reduce linq usage (faster save retrieval) misc4 line endings?
This commit is contained in:
parent
43838a5f24
commit
21ab0296f3
6 changed files with 38 additions and 26 deletions
|
@ -172,11 +172,15 @@ namespace PKHeX.Core
|
|||
}
|
||||
public override PKM getPKM(byte[] data)
|
||||
{
|
||||
return new PK3(data.Take(PKX.SIZE_3STORED).ToArray());
|
||||
if (data.Length != PKX.SIZE_3STORED)
|
||||
Array.Resize(ref data, PKX.SIZE_3STORED);
|
||||
return new PK3(data);
|
||||
}
|
||||
public override byte[] decryptPKM(byte[] data)
|
||||
{
|
||||
return PKX.decryptArray3(data.Take(PKX.SIZE_3STORED).ToArray());
|
||||
if (data.Length != PKX.SIZE_3STORED)
|
||||
Array.Resize(ref data, PKX.SIZE_3STORED);
|
||||
return PKX.decryptArray3(data);
|
||||
}
|
||||
|
||||
protected override void setDex(PKM pkm) { }
|
||||
|
|
|
@ -86,8 +86,8 @@ namespace PKHeX.Core
|
|||
if (c == null)
|
||||
return;
|
||||
|
||||
BitConverter.GetBytes(SaveUtil.ccitt16(getData(c[0][0] + GBO, c[0][1] - c[0][0]))).CopyTo(Data, c[0][2] + GBO);
|
||||
BitConverter.GetBytes(SaveUtil.ccitt16(getData(c[1][0] + SBO, c[1][1] - c[1][0]))).CopyTo(Data, c[1][2] + SBO);
|
||||
BitConverter.GetBytes(SaveUtil.ccitt16(Data, c[0][0] + GBO, c[0][1] - c[0][0])).CopyTo(Data, c[0][2] + GBO);
|
||||
BitConverter.GetBytes(SaveUtil.ccitt16(Data, c[1][0] + SBO, c[1][1] - c[1][0])).CopyTo(Data, c[1][2] + SBO);
|
||||
}
|
||||
public override bool ChecksumsValid
|
||||
{
|
||||
|
@ -97,9 +97,9 @@ namespace PKHeX.Core
|
|||
if (c == null)
|
||||
return false;
|
||||
|
||||
if (SaveUtil.ccitt16(getData(c[0][0] + GBO, c[0][1] - c[0][0])) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
|
||||
if (SaveUtil.ccitt16(Data, c[0][0] + GBO, c[0][1] - c[0][0]) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
|
||||
return false; // Small Fail
|
||||
if (SaveUtil.ccitt16(getData(c[1][0] + SBO, c[1][1] - c[1][0])) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
|
||||
if (SaveUtil.ccitt16(Data, c[1][0] + SBO, c[1][1] - c[1][0]) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
|
||||
return false; // Large Fail
|
||||
|
||||
return true;
|
||||
|
@ -114,9 +114,9 @@ namespace PKHeX.Core
|
|||
return "Unable to check Save File.";
|
||||
|
||||
string r = "";
|
||||
if (SaveUtil.ccitt16(getData(c[0][0] + GBO, c[0][1] - c[0][0])) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
|
||||
if (SaveUtil.ccitt16(Data, c[0][0] + GBO, c[0][1] - c[0][0]) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
|
||||
r += "Small block checksum is invalid" + Environment.NewLine;
|
||||
if (SaveUtil.ccitt16(getData(c[1][0] + SBO, c[1][1] - c[1][0])) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
|
||||
if (SaveUtil.ccitt16(Data, c[1][0] + SBO, c[1][1] - c[1][0]) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
|
||||
r += "Large block checksum is invalid" + Environment.NewLine;
|
||||
|
||||
return r.Length == 0 ? "Checksums valid." : r.TrimEnd();
|
||||
|
|
|
@ -229,20 +229,21 @@ namespace PKHeX.Core
|
|||
if (!new[] { SIZE_G3BOX, SIZE_G3BOXGCI }.Contains(data.Length))
|
||||
return GameVersion.Invalid;
|
||||
|
||||
byte[] sav = data.Skip(data.Length - SIZE_G3BOX).Take(SIZE_G3BOX).ToArray();
|
||||
byte[] sav = data;
|
||||
|
||||
// Verify first checksum
|
||||
uint chk = 0; // initial value
|
||||
var ofs = data.Length - SIZE_G3BOX + 0x2000;
|
||||
for (int j = 0x4; j < 0x1FFC; j += 2)
|
||||
{
|
||||
chk += (ushort)(sav[0x2000 + j] << 8);
|
||||
chk += sav[0x2000 + j + 1];
|
||||
chk += (ushort)(sav[ofs + j] << 8);
|
||||
chk += sav[ofs + j + 1];
|
||||
}
|
||||
ushort chkA = (ushort)chk;
|
||||
ushort chkB = (ushort)(0xF004 - chkA);
|
||||
|
||||
ushort CHK_A = (ushort)((sav[0x2000] << 8) | sav[0x2001]);
|
||||
ushort CHK_B = (ushort)((sav[0x2002] << 8) | sav[0x2003]);
|
||||
ushort CHK_A = (ushort)((sav[ofs + 0] << 8) | sav[ofs + 1]);
|
||||
ushort CHK_B = (ushort)((sav[ofs + 2] << 8) | sav[ofs + 3]);
|
||||
|
||||
return CHK_A == chkA && CHK_B == chkB ? GameVersion.RSBOX : GameVersion.Invalid;
|
||||
}
|
||||
|
@ -295,11 +296,11 @@ namespace PKHeX.Core
|
|||
return GameVersion.Invalid;
|
||||
|
||||
// General Block Checksum
|
||||
if (BitConverter.ToUInt16(data, 0xC0FE) == ccitt16(data.Take(0xC0EC).ToArray()))
|
||||
if (BitConverter.ToUInt16(data, 0xC0FE) == ccitt16(data, 0, 0xC0EC))
|
||||
return GameVersion.DP;
|
||||
if (BitConverter.ToUInt16(data, 0xCF2A) == ccitt16(data.Take(0xCF18).ToArray()))
|
||||
if (BitConverter.ToUInt16(data, 0xCF2A) == ccitt16(data, 0, 0xCF18))
|
||||
return GameVersion.Pt;
|
||||
if (BitConverter.ToUInt16(data, 0xF626) == ccitt16(data.Take(0xF618).ToArray()))
|
||||
if (BitConverter.ToUInt16(data, 0xF626) == ccitt16(data, 0, 0xF618))
|
||||
return GameVersion.HGSS;
|
||||
|
||||
// General Block Checksum is invalid, check for block identifiers
|
||||
|
@ -346,11 +347,11 @@ namespace PKHeX.Core
|
|||
return GameVersion.Invalid;
|
||||
|
||||
ushort chk1 = BitConverter.ToUInt16(data, SIZE_G5BW - 0x100 + 0x8C + 0xE);
|
||||
ushort actual1 = ccitt16(data.Skip(SIZE_G5BW - 0x100).Take(0x8C).ToArray());
|
||||
ushort actual1 = ccitt16(data, SIZE_G5BW - 0x100, 0x8C);
|
||||
if (chk1 == actual1)
|
||||
return GameVersion.BW;
|
||||
ushort chk2 = BitConverter.ToUInt16(data, SIZE_G5B2W2 - 0x100 + 0x94 + 0xE);
|
||||
ushort actual2 = ccitt16(data.Skip(SIZE_G5B2W2 - 0x100).Take(0x94).ToArray());
|
||||
ushort actual2 = ccitt16(data, SIZE_G5B2W2 - 0x100, 0x94);
|
||||
if (chk2 == actual2)
|
||||
return GameVersion.B2W2;
|
||||
return GameVersion.Invalid;
|
||||
|
@ -590,15 +591,19 @@ namespace PKHeX.Core
|
|||
// SAV Manipulation
|
||||
/// <summary>Calculates the CRC16-CCITT checksum over an input byte array.</summary>
|
||||
/// <param name="data">Input byte array</param>
|
||||
/// <param name="start">Starting point for checksum</param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns>Checksum</returns>
|
||||
public static ushort ccitt16(byte[] data)
|
||||
public static ushort ccitt16(byte[] data, int start, int length)
|
||||
{
|
||||
const ushort init = 0xFFFF;
|
||||
const ushort poly = 0x1021;
|
||||
|
||||
ushort crc = init;
|
||||
foreach (byte b in data)
|
||||
int end = start + length;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
byte b = data[i];
|
||||
crc ^= (ushort)(b << 8);
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
|
@ -611,6 +616,11 @@ namespace PKHeX.Core
|
|||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>Calculates the CRC16-CCITT checksum over an input byte array.</summary>
|
||||
/// <param name="data">Input byte array</param>
|
||||
/// <returns>Checksum</returns>
|
||||
public static ushort ccitt16(byte[] data) => ccitt16(data, 0, data.Length);
|
||||
|
||||
private static readonly ushort[] crc16 =
|
||||
{
|
||||
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
||||
|
|
|
@ -491,7 +491,8 @@ namespace PKHeX.WinForms
|
|||
if (Prints[i] == 1 + Math.Sign((BitConverter.ToUInt16(SAV.Data, ofsPrints + (i << 1)) >> 1) - 1)) continue;
|
||||
BitConverter.GetBytes(Prints[i] << 1).CopyTo(SAV.Data, ofsPrints + (i << 1));
|
||||
}
|
||||
if (HallStatUpdated) BitConverter.GetBytes(SaveUtil.ccitt16(SAV.Data.Skip(ofsHallStat).Take(0xBAE).ToArray())).CopyTo(SAV.Data, ofsHallStat + 0xBAE);
|
||||
if (HallStatUpdated)
|
||||
BitConverter.GetBytes(SaveUtil.ccitt16(SAV.Data, ofsHallStat, 0xBAE)).CopyTo(SAV.Data, ofsHallStat + 0xBAE);
|
||||
}
|
||||
|
||||
private void setPrints()
|
||||
|
|
|
@ -122,15 +122,12 @@ namespace PKHeX.WinForms
|
|||
BitConverter.GetBytes(chk).CopyTo(SAV.Data, SAV.CGearDataOffset + bgdata.Length + 2);
|
||||
BitConverter.GetBytes(chk).CopyTo(SAV.Data, SAV.CGearDataOffset + bgdata.Length + 0x100);
|
||||
|
||||
byte[] skinchkdata = SAV.Data.Skip(SAV.CGearDataOffset + bgdata.Length + 0x100).Take(4).ToArray();
|
||||
ushort skinchkval = SaveUtil.ccitt16(skinchkdata);
|
||||
ushort skinchkval = SaveUtil.ccitt16(SAV.Data, bgdata.Length + 0x100, 4);
|
||||
BitConverter.GetBytes(skinchkval).CopyTo(SAV.Data, SAV.CGearDataOffset + bgdata.Length + 0x112);
|
||||
|
||||
// Indicate in the save file that data is present
|
||||
BitConverter.GetBytes((ushort)0xC21E).CopyTo(SAV.Data, 0x19438);
|
||||
|
||||
|
||||
|
||||
SAV.Data[SAV.CGearInfoOffset + 0x26] = 1; // data present
|
||||
BitConverter.GetBytes(chk).CopyTo(SAV.Data, SAV.CGearInfoOffset + 0x24);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace PKHeX.WinForms
|
|||
Array.Copy(LinkInfo.Data, 0, data, 0x1FF, LinkInfo.Data.Length);
|
||||
|
||||
// Fix Checksum just in case.
|
||||
ushort ccitt = SaveUtil.ccitt16(data.Skip(0x200).Take(data.Length - 4 - 0x200).ToArray()); // [app,chk)
|
||||
ushort ccitt = SaveUtil.ccitt16(data, 0x200, data.Length - 4 - 0x200); // [app,chk)
|
||||
BitConverter.GetBytes(ccitt).CopyTo(data, data.Length - 4);
|
||||
|
||||
SAV.LinkBlock = data;
|
||||
|
|
Loading…
Reference in a new issue