Altered SaveUtil to be usable from external assemblies

This commit is contained in:
Evan Dixon 2016-06-26 13:46:08 -05:00
parent ca139cf7e4
commit 86b2090ba1

View file

@ -17,7 +17,32 @@ namespace PKHeX
DP = 100,
HGSS = 101,
}
internal static class SaveUtil
public enum Gen4Version
{
Invalid = -1,
DP = 0,
Pt = 1,
HGSS = 2
}
public enum Gen5Version
{
Invalid = -1,
BW = 0,
B2W2 = 1
}
public enum Gen6Version
{
Invalid = -1,
XY = 0,
ORASDEMO = 1,
ORAS = 2,
Default = 3 //Todo: rename this to something else; referenced in getIsG6SAV
}
public static class SaveUtil
{
internal const int BEEF = 0x42454546;
@ -31,75 +56,94 @@ namespace PKHeX
internal static readonly byte[] FOOTER_DSV = Encoding.ASCII.GetBytes("|-DESMUME SAVE-|");
internal static int getSAVGeneration(byte[] data)
/// <summary>
/// Determines the generation of the given save data.
/// </summary>
/// <param name="data">Save data of which to determine the generation</param>
/// <returns>The generation of the save file (i.e. 4, 5, or 6), or -1 if the generation cannot be determined.</returns>
public static int getSAVGeneration(byte[] data)
{
if (getIsG4SAV(data) != -1)
if (getIsG4SAV(data) != Gen4Version.Invalid)
return 4;
if (getIsG5SAV(data) != -1)
return 5;
if (getIsG6SAV(data) != -1)
if (getIsG6SAV(data) != Gen6Version.Invalid)
return 6;
return -1;
}
internal static int getIsG4SAV(byte[] data)
/// <summary>
/// Determines the type of 4th gen save
/// </summary>
/// <param name="data">Save data of which to determine the type</param>
/// <returns></returns>
public static Gen4Version getIsG4SAV(byte[] data)
{
if (data.Length != SIZE_G4RAW)
return -1;
return Gen4Version.Invalid;
// General Block Checksum
if (BitConverter.ToUInt16(data, 0xC0FE) == ccitt16(data.Take(0xC0EC).ToArray()))
return 0; // DP
return Gen4Version.DP;
if (BitConverter.ToUInt16(data, 0xCF2A) == ccitt16(data.Take(0xCF18).ToArray()))
return 1; // Pt
return Gen4Version.Pt;
if (BitConverter.ToUInt16(data, 0xF626) == ccitt16(data.Take(0xF618).ToArray()))
return 2; // HGSS
return Gen4Version.HGSS;
// General Block Checksum is invalid, check for block identifiers
if (data.Skip(0xC0F4).Take(10).SequenceEqual(new byte[] { 0x00, 0xC1, 0x00, 0x00, 0x23, 0x06, 0x06, 0x20, 0x00, 0x00 }))
return 0; // DP
return Gen4Version.DP;
if (data.Skip(0xCF20).Take(10).SequenceEqual(new byte[] { 0x2C, 0xCF, 0x00, 0x00, 0x23, 0x06, 0x06, 0x20, 0x00, 0x00 }))
return 1; // Pt
return Gen4Version.Pt;
if (data.Skip(0xF61C).Take(10).SequenceEqual(new byte[] { 0x28, 0xF6, 0x00, 0x00, 0x23, 0x06, 0x06, 0x20, 0x00, 0x00 }))
return 2; // HGSS
return Gen4Version.HGSS;
return -1;
return Gen4Version.Invalid;
}
internal static int getIsG5SAV(byte[] data)
public static Gen5Version getIsG5SAV(byte[] data)
{
if (data.Length != SIZE_G5RAW)
return -1;
return Gen5Version.Invalid;
ushort chk1 = BitConverter.ToUInt16(data, SIZE_G5BW - 0x100 + 0x8C + 0xE);
ushort actual1 = ccitt16(data.Skip(SIZE_G5BW - 0x100).Take(0x8C).ToArray());
if (chk1 == actual1)
return 0;
return Gen5Version.BW;
ushort chk2 = BitConverter.ToUInt16(data, SIZE_G5B2W2 - 0x100 + 0x94 + 0xE);
ushort actual2 = ccitt16(data.Skip(SIZE_G5B2W2 - 0x100).Take(0x94).ToArray());
if (chk2 == actual2)
return 1;
return -1;
return Gen5Version.B2W2;
return Gen5Version.Invalid;
}
internal static int getIsG6SAV(byte[] data)
public static Gen6Version getIsG6SAV(byte[] data)
{
if (!SizeValidSAV6(data.Length))
return -1;
return Gen6Version.Invalid;
if (BitConverter.ToUInt32(data, data.Length - 0x1F0) != BEEF)
return -1;
return Gen6Version.Invalid;
switch (data.Length)
{
case SIZE_G6XY:
return 0;
return Gen6Version.XY;
case SIZE_G6ORASDEMO:
return 1;
return Gen6Version.ORASDEMO;
case SIZE_G6ORAS:
return 2;
return Gen6Version.ORAS;
default: // won't hit
return 3;
return Gen6Version.Default;
}
}
internal static SaveFile getVariantSAV(byte[] data)
/// <summary>
/// Creates an instance of a SaveFile using the given save data.
/// </summary>
/// <param name="data">Save data from which to create a SaveFile.</param>
/// <returns>An appropriate type of save file for the given data, or null if the save data is invalid.</returns>
public static SaveFile getVariantSAV(byte[] data)
{
switch (getSAVGeneration(data))
{
@ -113,7 +157,13 @@ namespace PKHeX
return null;
}
}
internal static bool SizeValidSAV6(int size)
/// <summary>
/// Determines whether the save data size is valid for 6th generation saves.
/// </summary>
/// <param name="size">Size in bytes of the save data</param>
/// <returns>A boolean indicating whether or not the save data size is valid.</returns>
public static bool SizeValidSAV6(int size)
{
switch (size)
{
@ -129,7 +179,7 @@ namespace PKHeX
/// <summary>Calculates the CRC16-CCITT checksum over an input byte array.</summary>
/// <param name="data">Input byte array</param>
/// <returns>Checksum</returns>
internal static ushort ccitt16(byte[] data)
public static ushort ccitt16(byte[] data)
{
const ushort init = 0xFFFF;
const ushort poly = 0x1021;
@ -151,7 +201,7 @@ namespace PKHeX
/// <summary>Simple check to see if the save is valid.</summary>
/// <param name="savefile">Input binary file</param>
/// <returns>True/False</returns>
internal static bool verifyG6SAV(byte[] savefile)
public static bool verifyG6SAV(byte[] savefile)
{
// Dynamic handling of checksums regardless of save size.
@ -193,7 +243,7 @@ namespace PKHeX
/// <summary>Verbose check to see if the save is valid.</summary>
/// <param name="savefile">Input binary file</param>
/// <returns>String containing invalid blocks.</returns>
internal static string verifyG6CHK(byte[] savefile)
public static string verifyG6CHK(byte[] savefile)
{
string rv = "";
int invalid = 0;
@ -241,7 +291,7 @@ namespace PKHeX
/// <summary>Fix checksums in the input save file.</summary>
/// <param name="savefile">Input binary file</param>
/// <returns>Fixed save file.</returns>
internal static void writeG6CHK(byte[] savefile)
public static void writeG6CHK(byte[] savefile)
{
// Dynamic handling of checksums regardless of save size.
@ -277,7 +327,7 @@ namespace PKHeX
}
}
internal static int getDexFormIndexXY(int species, int formct)
public static int getDexFormIndexXY(int species, int formct)
{
if (formct < 1 || species < 0)
return -1; // invalid
@ -343,7 +393,7 @@ namespace PKHeX
default: return -1;
}
}
internal static int getDexFormIndexORAS(int species, int formct)
public static int getDexFormIndexORAS(int species, int formct)
{
if (formct < 1 || species < 0)
return -1; // invalid