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 @@ 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); } 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 @@ 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(); 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 @@ 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(); 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 @@ 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); 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 @@ 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) {