2014-07-22 05:47:18 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2014-10-10 02:59:57 +00:00
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Text.RegularExpressions;
|
2014-07-22 05:47:18 +00:00
|
|
|
|
using System.Security.Cryptography;
|
2014-10-10 02:59:57 +00:00
|
|
|
|
using System.Collections.Generic;
|
2014-07-24 16:20:08 +00:00
|
|
|
|
using System.Reflection;
|
2014-10-10 02:59:57 +00:00
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
2014-07-22 05:47:18 +00:00
|
|
|
|
namespace PKHeX
|
|
|
|
|
{
|
2014-10-10 02:59:57 +00:00
|
|
|
|
public partial class frmReport : Form1
|
2014-07-22 05:47:18 +00:00
|
|
|
|
{
|
|
|
|
|
private byte[] SaveData;
|
|
|
|
|
private const int PIDOFFSET = 0x18;
|
|
|
|
|
private const int TIDOFFSET = 0x0C;
|
|
|
|
|
private const int SIDOFFSET = 0x0E;
|
2014-07-24 16:20:08 +00:00
|
|
|
|
static Form1 m_parent;
|
|
|
|
|
public frmReport(Form1 frm1)
|
2014-07-22 05:47:18 +00:00
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2014-07-24 16:20:08 +00:00
|
|
|
|
m_parent = frm1;
|
|
|
|
|
dgData.DoubleBuffered(true);
|
2014-07-22 05:47:18 +00:00
|
|
|
|
}
|
|
|
|
|
private static uint LCRNG(uint seed)
|
|
|
|
|
{
|
|
|
|
|
uint a = 0x41C64E6D;
|
|
|
|
|
uint c = 0x00006073;
|
|
|
|
|
|
|
|
|
|
seed = (seed * a + c) & 0xFFFFFFFF;
|
|
|
|
|
return seed;
|
|
|
|
|
}
|
|
|
|
|
public byte[] shuffleArray(byte[] pkx, uint sv)
|
|
|
|
|
{
|
|
|
|
|
byte[] ekx = new Byte[260];
|
|
|
|
|
Array.Copy(pkx, ekx, 8);
|
|
|
|
|
|
|
|
|
|
// Now to shuffle the blocks
|
|
|
|
|
|
|
|
|
|
// Define Shuffle Order Structure
|
|
|
|
|
var aloc = new byte[] { 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 2, 3, 1, 1, 2, 3, 2, 3, 1, 1, 2, 3, 2, 3 };
|
|
|
|
|
var bloc = new byte[] { 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 0, 0, 2, 3, 1, 1, 3, 2, 2, 3, 1, 1, 3, 2 };
|
|
|
|
|
var cloc = new byte[] { 2, 3, 1, 1, 3, 2, 2, 3, 1, 1, 3, 2, 0, 0, 0, 0, 0, 0, 3, 2, 3, 2, 1, 1 };
|
|
|
|
|
var dloc = new byte[] { 3, 2, 3, 2, 1, 1, 3, 2, 3, 2, 1, 1, 3, 2, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0 };
|
|
|
|
|
|
|
|
|
|
// Get Shuffle Order
|
|
|
|
|
var shlog = new byte[] { aloc[sv], bloc[sv], cloc[sv], dloc[sv] };
|
|
|
|
|
|
|
|
|
|
// UnShuffle Away!
|
|
|
|
|
for (int b = 0; b < 4; b++)
|
|
|
|
|
{
|
|
|
|
|
Array.Copy(pkx, 8 + 56 * shlog[b], ekx, 8 + 56 * b, 56);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fill the Battle Stats back
|
|
|
|
|
if (pkx.Length > 232)
|
|
|
|
|
{
|
|
|
|
|
Array.Copy(pkx, 232, ekx, 232, 28);
|
|
|
|
|
}
|
|
|
|
|
return ekx;
|
|
|
|
|
}
|
|
|
|
|
public byte[] decryptArray(byte[] ekx)
|
|
|
|
|
{
|
|
|
|
|
byte[] pkx = ekx;
|
|
|
|
|
uint pv = BitConverter.ToUInt32(pkx, 0);
|
|
|
|
|
uint sv = (((pv & 0x3E000) >> 0xD) % 24);
|
|
|
|
|
|
|
|
|
|
uint seed = pv;
|
|
|
|
|
|
|
|
|
|
// Decrypt Blocks with RNG Seed
|
|
|
|
|
for (int i = 8; i < 232; i += 2)
|
|
|
|
|
{
|
|
|
|
|
int pre = pkx[i] + ((pkx[i + 1]) << 8);
|
|
|
|
|
seed = LCRNG(seed);
|
|
|
|
|
int seedxor = (int)((seed) >> 16);
|
|
|
|
|
int post = (pre ^ seedxor);
|
|
|
|
|
pkx[i] = (byte)((post) & 0xFF);
|
|
|
|
|
pkx[i + 1] = (byte)(((post) >> 8) & 0xFF);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deshuffle
|
|
|
|
|
pkx = shuffleArray(pkx, sv);
|
|
|
|
|
|
|
|
|
|
// Decrypt the Party Stats
|
|
|
|
|
seed = pv;
|
|
|
|
|
for (int i = 232; i < 260; i += 2)
|
|
|
|
|
{
|
|
|
|
|
int pre = pkx[i] + ((pkx[i + 1]) << 8);
|
|
|
|
|
seed = LCRNG(seed);
|
|
|
|
|
int seedxor = (int)((seed) >> 16);
|
|
|
|
|
int post = (pre ^ seedxor);
|
|
|
|
|
pkx[i] = (byte)((post) & 0xFF);
|
|
|
|
|
pkx[i + 1] = (byte)(((post) >> 8) & 0xFF);
|
|
|
|
|
}
|
|
|
|
|
return pkx;
|
|
|
|
|
}
|
|
|
|
|
private UInt16 getTSV(UInt32 PID, UInt16 TID, UInt16 SID)
|
|
|
|
|
{
|
|
|
|
|
UInt16 tsv = Convert.ToUInt16((TID ^ SID) >> 4);
|
|
|
|
|
return Convert.ToUInt16(((PID >> 16) ^ (PID & 0xFFFF)) >> 4);
|
|
|
|
|
}
|
|
|
|
|
private int detectSAVIndex(byte[] data)
|
|
|
|
|
{
|
|
|
|
|
int savindex = 0;
|
|
|
|
|
SHA256 mySHA256 = SHA256Managed.Create();
|
|
|
|
|
{
|
|
|
|
|
byte[] difihash1 = new Byte[0x12C];
|
|
|
|
|
byte[] difihash2 = new Byte[0x12C];
|
|
|
|
|
Array.Copy(data, 0x330, difihash1, 0, 0x12C);
|
|
|
|
|
Array.Copy(data, 0x200, difihash2, 0, 0x12C);
|
|
|
|
|
byte[] hashValue1 = mySHA256.ComputeHash(difihash1);
|
|
|
|
|
byte[] hashValue2 = mySHA256.ComputeHash(difihash2);
|
|
|
|
|
byte[] actualhash = new Byte[0x20];
|
|
|
|
|
Array.Copy(data, 0x16C, actualhash, 0, 0x20);
|
|
|
|
|
if (hashValue1.SequenceEqual(actualhash))
|
|
|
|
|
{
|
|
|
|
|
savindex = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (hashValue2.SequenceEqual(actualhash))
|
|
|
|
|
{
|
|
|
|
|
savindex = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
savindex = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((data[0x168] ^ 1) != savindex && savindex != 2)
|
|
|
|
|
{
|
|
|
|
|
savindex = 2;
|
|
|
|
|
}
|
|
|
|
|
return savindex;
|
|
|
|
|
}
|
|
|
|
|
public void PopulateData(byte[] InputData)
|
|
|
|
|
{
|
|
|
|
|
//IList<PKX> PL = new List<PKX>();
|
|
|
|
|
SaveData = new byte[InputData.Length];
|
|
|
|
|
Array.Copy(InputData, SaveData, InputData.Length);
|
|
|
|
|
PokemonList PL = new PokemonList();
|
|
|
|
|
SaveGames.SaveStruct SaveGame = new SaveGames.SaveStruct("XY");
|
|
|
|
|
int savindex = detectSAVIndex(SaveData);
|
2014-07-24 16:20:08 +00:00
|
|
|
|
if (savindex > 1) savindex = 0;
|
2014-07-22 05:47:18 +00:00
|
|
|
|
for (int BoxNum = 0; BoxNum < 31; BoxNum++)
|
|
|
|
|
{
|
|
|
|
|
int boxoffset = 0x27A00 + 0x7F000 * savindex + BoxNum * (0xE8 * 30);
|
|
|
|
|
for (int SlotNum = 0; SlotNum < 30; SlotNum++)
|
|
|
|
|
{
|
|
|
|
|
int offset = boxoffset + 0xE8 * SlotNum;
|
|
|
|
|
byte[] slotdata = new Byte[0xE8];
|
|
|
|
|
Array.Copy(SaveData, offset, slotdata, 0, 0xE8);
|
|
|
|
|
byte[] dslotdata = decryptArray(slotdata);
|
|
|
|
|
PKX pkm = new PKX(dslotdata);
|
2014-07-26 21:56:06 +00:00
|
|
|
|
if ((pkm.EC == "00000000") && (pkm.Species == "---")) continue;
|
2014-07-22 05:47:18 +00:00
|
|
|
|
PL.Add(pkm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dgData.DataSource = PL;
|
|
|
|
|
dgData.AutoGenerateColumns = true;
|
|
|
|
|
}
|
|
|
|
|
public static string TrimFromZero(string input)
|
|
|
|
|
{
|
|
|
|
|
int index = input.IndexOf('\0');
|
|
|
|
|
if (index < 0)
|
|
|
|
|
return input;
|
|
|
|
|
|
|
|
|
|
return input.Substring(0, index);
|
|
|
|
|
}
|
|
|
|
|
public class PokemonList : System.Collections.ObjectModel.ObservableCollection<PKX> { }
|
|
|
|
|
}
|
2014-07-24 16:20:08 +00:00
|
|
|
|
public static class ExtensionMethods // Speed up scrolling
|
|
|
|
|
{
|
|
|
|
|
public static void DoubleBuffered(this DataGridView dgv, bool setting)
|
|
|
|
|
{
|
|
|
|
|
Type dgvType = dgv.GetType();
|
|
|
|
|
PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
|
pi.SetValue(dgv, setting, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-07-22 05:47:18 +00:00
|
|
|
|
}
|