mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-28 02:25:06 -05:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user