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 @@ namespace PKHeX
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 @@ namespace PKHeX
#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 @@ namespace PKHeX
SaveFileDialog main = new SaveFileDialog
{
Filter = "Main SAV|*.*",
Filter = SAV.Filter,
FileName = SAV.FileName,
RestoreDirectory = true
};
@ -3153,7 +3165,9 @@ namespace PKHeX
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 @@ namespace PKHeX
{
// 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 @@ namespace PKHeX
{
// 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 @@ namespace PKHeX
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 @@ namespace PKHeX
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 @@ namespace PKHeX
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 @@ namespace PKHeX
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)
{