From e6a4f4cce13e8200bc356c95585f74a76e1fa07b Mon Sep 17 00:00:00 2001 From: Kaphotics Date: Sun, 19 Jun 2016 22:11:53 -0700 Subject: [PATCH] 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. --- PKX/f1-Main.cs | 20 +++++++++++++++++--- Saves/SAV4.cs | 2 ++ Saves/SAV5.cs | 2 ++ Saves/SAV6.cs | 2 ++ Saves/SaveFile.cs | 9 +++++++-- Saves/SaveUtil.cs | 5 ++--- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/PKX/f1-Main.cs b/PKX/f1-Main.cs index 153d0f277..83e0ba37b 100644 --- a/PKX/f1-Main.cs +++ b/PKX/f1-Main.cs @@ -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); } diff --git a/Saves/SAV4.cs b/Saves/SAV4.cs index 36b90303a..9867a1f7a 100644 --- a/Saves/SAV4.cs +++ b/Saves/SAV4.cs @@ -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(); diff --git a/Saves/SAV5.cs b/Saves/SAV5.cs index b9c031a5d..81c40cf11 100644 --- a/Saves/SAV5.cs +++ b/Saves/SAV5.cs @@ -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(); diff --git a/Saves/SAV6.cs b/Saves/SAV6.cs index 882a8e428..e7b73b445 100644 --- a/Saves/SAV6.cs +++ b/Saves/SAV6.cs @@ -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(); diff --git a/Saves/SaveFile.cs b/Saves/SaveFile.cs index de8039182..717fddf86 100644 --- a/Saves/SaveFile.cs +++ b/Saves/SaveFile.cs @@ -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); diff --git a/Saves/SaveUtil.cs b/Saves/SaveUtil.cs index e8c05db91..cd0dc462d 100644 --- a/Saves/SaveUtil.cs +++ b/Saves/SaveUtil.cs @@ -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) {