Add .dsv support

Even catches the 1MB misconfigured DSV's (stuffs the bak data in with
the footer).

Works by searching for the DeSmuME footer signature in the input data,
if present, breaking up the info.
This commit is contained in:
Kaphotics
2016-06-19 22:11:53 -07:00
parent e784389ad2
commit e6a4f4cce1
6 changed files with 32 additions and 8 deletions

View File

@@ -512,6 +512,18 @@ private void openQuick(string path, bool force = false)
private void openFile(byte[] input, string path, string ext)
{
MysteryGift tg; PKM temp; string c;
byte[] footer = new byte[0];
#region DeSmuME .dsv detect
if (input.Length > SaveUtil.SIZE_G4RAW)
{
bool dsv = SaveUtil.FOOTER_DSV.SequenceEqual(input.Skip(input.Length - SaveUtil.FOOTER_DSV.Length).Take(SaveUtil.FOOTER_DSV.Length));
if (dsv)
{
footer = input.Skip(SaveUtil.SIZE_G4RAW).ToArray();
input = input.Take(SaveUtil.SIZE_G4RAW).ToArray();
}
}
#endregion
#region Powersaves Read-Only Conversion
if (input.Length == 0x10009C) // Resize to 1MB
{
@@ -541,7 +553,7 @@ private void openFile(byte[] input, string path, string ext)
#endregion
#region SAV/PKM
else if (SaveUtil.getSAVGeneration(input) > -1) // Supports Gen4/5/6
openSAV(input, path);
{ openSAV(input, path); SAV.Footer = footer; }
else if ((temp = PKMConverter.getPKMfromBytes(input)) != null)
{
PKM pk = PKMConverter.convertToFormat(temp, SAV.Generation, out c);
@@ -3141,7 +3153,7 @@ private void clickExportSAV(object sender, EventArgs e)
SaveFileDialog main = new SaveFileDialog
{
Filter = "Main SAV|*.*",
Filter = SAV.Filter,
FileName = SAV.FileName,
RestoreDirectory = true
};
@@ -3153,7 +3165,9 @@ private void clickExportSAV(object sender, EventArgs e)
if (SAV.HasBox)
SAV.CurrentBox = CB_BoxSelect.SelectedIndex;
File.WriteAllBytes(main.FileName, SAV.Write());
bool dsv = Path.GetExtension(main.FileName).ToLower() == ".dsv";
File.WriteAllBytes(main.FileName, SAV.Write(dsv));
Util.Alert("SAV exported to:", main.FileName);
}

View File

@@ -6,6 +6,8 @@ namespace PKHeX
public sealed class SAV4 : SaveFile
{
public override string BAKName => $"{FileName} [{OT} ({Version})" +/* - {LastSavedTime}*/ "].bak";
public override string Filter => (Footer.Length > 0 ? "DeSmuME DSV|*.dsv|" : "") + "SAV File|*.sav";
public override string Extension => ".sav";
public SAV4(byte[] data = null)
{
Data = data == null ? new byte[SaveUtil.SIZE_G4RAW] : (byte[])data.Clone();

View File

@@ -8,6 +8,8 @@ public sealed class SAV5 : SaveFile
{
// Save Data Attributes
public override string BAKName => $"{FileName} [{OT} ({Version})" +/* - {LastSavedTime}*/ "].bak";
public override string Filter => (Footer.Length > 0 ? "DeSmuME DSV|*.dsv|" : "") + "SAV File|*.sav*";
public override string Extension => ".sav";
public SAV5(byte[] data = null)
{
Data = data == null ? new byte[SaveUtil.SIZE_G5RAW] : (byte[])data.Clone();

View File

@@ -8,6 +8,8 @@ public sealed class SAV6 : SaveFile
{
// Save Data Attributes
public override string BAKName => $"{FileName} [{OT} ({Version}) - {LastSavedTime}].bak";
public override string Filter => "Main SAV|*.*";
public override string Extension => "";
public SAV6(byte[] data = null)
{
Data = data == null ? new byte[SaveUtil.SIZE_G6ORAS] : (byte[])data.Clone();

View File

@@ -17,6 +17,8 @@ public abstract class SaveFile
public abstract byte[] BAK { get; }
public abstract bool Exportable { get; }
public abstract SaveFile Clone();
public abstract string Filter { get; }
public byte[] Footer { protected get; set; } // .dsv
// General PKM Properties
protected abstract Type PKMType { get; }
@@ -29,9 +31,11 @@ public abstract class SaveFile
public ushort[] HeldItems { get; protected set; }
// General SAV Properties
public byte[] Write()
public byte[] Write(bool DSV)
{
setChecksums();
if (Footer.Length > 0 && DSV)
return Data.Concat(Footer).ToArray();
return Data;
}
public virtual string MiscSaveChecks() { return ""; }
@@ -274,7 +278,8 @@ public virtual MysteryGiftAlbum GiftAlbum
public abstract int BoxCount { get; }
public abstract int PartyCount { get; protected set; }
public virtual int CurrentBox { get { return 0; } set { } }
public abstract string Extension { get; }
// Varied Methods
protected abstract void setChecksums();
public abstract int getBoxOffset(int box);

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Text;
namespace PKHeX
{
@@ -28,9 +29,7 @@ internal static class SaveUtil
internal const int SIZE_G5B2W2 = 0x26000;
internal const int SIZE_G4RAW = 0x80000;
internal static readonly byte[] EncryptedBlank4 = PKX.encryptArray45(new byte[PKX.SIZE_4PARTY]);
internal static readonly byte[] EncryptedBlank5 = PKX.encryptArray45(new byte[PKX.SIZE_5PARTY]);
internal static readonly byte[] EncryptedBlank6 = PKX.encryptArray(new byte[PKX.SIZE_6PARTY]);
internal static readonly byte[] FOOTER_DSV = Encoding.ASCII.GetBytes("|-DESMUME SAVE-|");
internal static int getSAVGeneration(byte[] data)
{