mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-07-29 17:07:42 -05:00
Extract metadata/state tracking from SaveFile obj
This commit is contained in:
parent
44473d1593
commit
e72c80613e
|
|
@ -50,9 +50,8 @@ public sealed class FakePKMEditor : IPKMView
|
|||
public sealed class FakeSaveFile : SaveFile
|
||||
{
|
||||
public static readonly FakeSaveFile Default = new FakeSaveFile();
|
||||
protected override string BAKText => "Fake Save File";
|
||||
public override SaveFile Clone() => this;
|
||||
public override string Filter => string.Empty;
|
||||
protected internal override string ShortSummary => "Fake Save File";
|
||||
protected override SaveFile CloneInternal() => this;
|
||||
public override string Extension => string.Empty;
|
||||
public override bool ChecksumsValid => true;
|
||||
public override string ChecksumInfo => string.Empty;
|
||||
|
|
|
|||
9
PKHeX.Core/Editing/Saves/Management/INamedFolderPath.cs
Normal file
9
PKHeX.Core/Editing/Saves/Management/INamedFolderPath.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public interface INamedFolderPath
|
||||
{
|
||||
string Path { get; }
|
||||
string DisplayText { get; }
|
||||
bool Custom { get; }
|
||||
}
|
||||
}
|
||||
49
PKHeX.Core/Editing/Saves/Management/SavePreview.cs
Normal file
49
PKHeX.Core/Editing/Saves/Management/SavePreview.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Bindable Summary of a <see cref="SaveFile"/> for use in a sortable table.
|
||||
/// </summary>
|
||||
public sealed class SavePreview
|
||||
{
|
||||
public readonly SaveFile Save;
|
||||
public readonly string FilePath;
|
||||
|
||||
public SavePreview(SaveFile sav, string parent, string path)
|
||||
{
|
||||
Save = sav;
|
||||
Folder = parent;
|
||||
FilePath = path;
|
||||
}
|
||||
|
||||
public SavePreview(SaveFile sav, List<INamedFolderPath> paths)
|
||||
{
|
||||
var meta = sav.Metadata;
|
||||
var dir = meta.FileFolder;
|
||||
const string notFound = "???";
|
||||
var parent = dir == null ? notFound : paths.Find(z => dir.StartsWith(z.Path))?.DisplayText ?? notFound;
|
||||
|
||||
Save = sav;
|
||||
Folder = parent;
|
||||
FilePath = meta.FilePath ?? notFound;
|
||||
}
|
||||
|
||||
public string OT => Save.OT;
|
||||
public int G => Save.Generation;
|
||||
public GameVersion Game => Save.Version;
|
||||
|
||||
public string Played => Save.PlayTimeString.PadLeft(9, '0');
|
||||
public string FileTime => File.GetLastWriteTimeUtc(FilePath).ToString("yyyy.MM.dd:hh:mm:ss");
|
||||
|
||||
public string TID => Save.Generation >= 7 ? Save.TrainerID7.ToString("000000") : Save.TID.ToString("00000");
|
||||
public string SID => Save.Generation >= 7 ? Save.TrainerSID7.ToString("0000") : Save.SID.ToString("00000");
|
||||
|
||||
// ReSharper disable once MemberCanBePrivate.Local
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public string Folder { get; }
|
||||
|
||||
public string Name => Path.GetFileName(FilePath);
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ public static bool InitFromSaveFileData(SaveFile sav)
|
|||
ActiveTrainer = sav;
|
||||
if (sav.Generation >= 3)
|
||||
return AllowGBCartEra = false;
|
||||
bool vc = !sav.Exportable || (sav.FileName?.EndsWith("dat") ?? false); // default to true for non-exportable
|
||||
bool vc = !sav.State.Exportable || (sav.Metadata.FileName?.EndsWith("dat") ?? false); // default to true for non-exportable
|
||||
return AllowGBCartEra = !vc; // physical cart selected
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV1 : SaveFile, ILangDeviantSave
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Filter => "SAV File|*.sav|All Files|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Extension => ".sav";
|
||||
|
||||
public int SaveRevision => Japanese ? 0 : 1;
|
||||
|
|
@ -184,7 +183,7 @@ private int GetBoxRawDataOffset(int i)
|
|||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone() => new SAV1(Write(), Version);
|
||||
protected override SaveFile CloneInternal() => new SAV1(Write(), Version);
|
||||
|
||||
protected override int SIZE_STORED => Japanese ? PokeCrypto.SIZE_1JLIST : PokeCrypto.SIZE_1ULIST;
|
||||
protected override int SIZE_PARTY => Japanese ? PokeCrypto.SIZE_1JLIST : PokeCrypto.SIZE_1ULIST;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public sealed class SAV1Stadium : SAV_STADIUM
|
|||
public override IReadOnlyList<ushort> HeldItems => Array.Empty<ushort>();
|
||||
public override GameVersion Version { get; protected set; } = GameVersion.Stadium;
|
||||
|
||||
public override SaveFile Clone() => new SAV1Stadium((byte[])Data.Clone(), Japanese);
|
||||
protected override SaveFile CloneInternal() => new SAV1Stadium((byte[])Data.Clone(), Japanese);
|
||||
|
||||
public override int Generation => 1;
|
||||
private int StringLength => Japanese ? StringLengthJ : StringLengthU;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public sealed class SAV1StadiumJ : SAV_STADIUM
|
|||
public override IReadOnlyList<ushort> HeldItems => Array.Empty<ushort>();
|
||||
public override GameVersion Version { get; protected set; } = GameVersion.StadiumJ;
|
||||
|
||||
public override SaveFile Clone() => new SAV1StadiumJ((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV1StadiumJ((byte[])Data.Clone());
|
||||
|
||||
public override int Generation => 1;
|
||||
private const int StringLength = 6; // Japanese Only
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV2 : SaveFile, ILangDeviantSave
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Filter => "SAV File|*.sav|All Files|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Extension => ".sav";
|
||||
|
||||
public int SaveRevision => Japanese ? 0 : !Korean ? 1 : 2;
|
||||
|
|
@ -247,7 +246,7 @@ protected override byte[] GetFinalData()
|
|||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone() => new SAV2(Write(), Version);
|
||||
protected override SaveFile CloneInternal() => new SAV2(Write(), Version);
|
||||
|
||||
protected override int SIZE_STORED => Japanese ? PokeCrypto.SIZE_2JLIST : PokeCrypto.SIZE_2ULIST;
|
||||
protected override int SIZE_PARTY => Japanese ? PokeCrypto.SIZE_2JLIST : PokeCrypto.SIZE_2ULIST;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public sealed class SAV2Stadium : SAV_STADIUM
|
|||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_GSC;
|
||||
public override GameVersion Version { get; protected set; } = GameVersion.Stadium2;
|
||||
|
||||
public override SaveFile Clone() => new SAV1Stadium((byte[])Data.Clone(), Japanese);
|
||||
protected override SaveFile CloneInternal() => new SAV1Stadium((byte[])Data.Clone(), Japanese);
|
||||
|
||||
public override int Generation => 2;
|
||||
private const int StringLength = 12;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV3 : SaveFile, ILangDeviantSave
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Filter => "SAV File|*.sav|All Files|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Extension => ".sav";
|
||||
|
||||
public int SaveRevision => Japanese ? 0 : 1;
|
||||
|
|
@ -285,7 +284,7 @@ protected override byte[] GetFinalData()
|
|||
public int GetBlockOffset(int block) => BlockOfs[block];
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone() => new SAV3(Write(), Version);
|
||||
protected override SaveFile CloneInternal() => new SAV3(Write(), Version);
|
||||
|
||||
protected override int SIZE_STORED => PokeCrypto.SIZE_3STORED;
|
||||
protected override int SIZE_PARTY => PokeCrypto.SIZE_3PARTY;
|
||||
|
|
@ -331,7 +330,7 @@ protected override void SetChecksums()
|
|||
BitConverter.GetBytes(chk).CopyTo(Data, ofs + 0xFF6);
|
||||
}
|
||||
|
||||
if (BAK.Length < SaveUtil.SIZE_G3RAW) // don't update HoF for half-sizes
|
||||
if (State.BAK.Length < SaveUtil.SIZE_G3RAW) // don't update HoF for half-sizes
|
||||
return;
|
||||
|
||||
// Hall of Fame Checksums
|
||||
|
|
@ -355,7 +354,7 @@ public override bool ChecksumsValid
|
|||
return false;
|
||||
}
|
||||
|
||||
if (BAK.Length < SaveUtil.SIZE_G3RAW) // don't check HoF for half-sizes
|
||||
if (State.BAK.Length < SaveUtil.SIZE_G3RAW) // don't check HoF for half-sizes
|
||||
return true;
|
||||
|
||||
if (!IsChunkValidHoF(0x1C000))
|
||||
|
|
@ -391,7 +390,7 @@ public override string ChecksumInfo
|
|||
list.Add($"Block {BlockOrder[i]:00} @ {i*SIZE_BLOCK:X5} invalid.");
|
||||
}
|
||||
|
||||
if (BAK.Length > SaveUtil.SIZE_G3RAW) // don't check HoF for half-sizes
|
||||
if (State.BAK.Length > SaveUtil.SIZE_G3RAW) // don't check HoF for half-sizes
|
||||
{
|
||||
if (!IsChunkValidHoF(0x1C000))
|
||||
list.Add("HoF Block 1 invalid.");
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV3Colosseum : SaveFile, IDisposable, IGCSaveFile
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Filter => this.GCFilter();
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Extension => this.GCExtension();
|
||||
public override PersonalTable Personal => PersonalTable.RS;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_COLO;
|
||||
|
|
@ -120,17 +119,16 @@ private byte[] GetInnerData()
|
|||
byte[] newSAV = EncryptColosseum(Data, digest);
|
||||
|
||||
// Put save slot back in original save data
|
||||
byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[])BAK.Clone();
|
||||
byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[]) State.BAK.Clone();
|
||||
Array.Copy(newSAV, 0, newFile, SLOT_START + (SaveIndex * SLOT_SIZE), newSAV.Length);
|
||||
return newFile;
|
||||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone()
|
||||
protected override SaveFile CloneInternal()
|
||||
{
|
||||
var data = GetInnerData();
|
||||
var sav = IsMemoryCardSave ? new SAV3Colosseum(data, MC!) : new SAV3Colosseum(data);
|
||||
sav.Header = (byte[])Header.Clone();
|
||||
return sav;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV3RSBox : SaveFile, IGCSaveFile
|
||||
{
|
||||
protected override string BAKText => $"{Version} #{SaveCount:0000}";
|
||||
public override string Filter => this.GCFilter();
|
||||
protected internal override string ShortSummary => $"{Version} #{SaveCount:0000}";
|
||||
public override string Extension => this.GCExtension();
|
||||
public override PersonalTable Personal => PersonalTable.RS;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_RS;
|
||||
|
|
@ -95,11 +94,10 @@ private byte[] GetInnerData()
|
|||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone()
|
||||
protected override SaveFile CloneInternal()
|
||||
{
|
||||
var data = GetInnerData();
|
||||
var sav = IsMemoryCardSave ? new SAV3RSBox(data, MC!) : new SAV3RSBox(data);
|
||||
sav.Header = (byte[])Header.Clone();
|
||||
return sav;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV3XD : SaveFile, IGCSaveFile
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) #{SaveCount:0000}";
|
||||
public override string Filter => this.GCFilter();
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) #{SaveCount:0000}";
|
||||
public override string Extension => this.GCExtension();
|
||||
public bool IsMemoryCardSave => MC != null;
|
||||
private readonly SAV3GCMemoryCard? MC;
|
||||
|
|
@ -144,17 +143,16 @@ private byte[] GetInnerData()
|
|||
byte[] newSAV = GCSaveUtil.Encrypt(Data, 0x10, 0x27FD8, keys);
|
||||
|
||||
// Put save slot back in original save data
|
||||
byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[])BAK.Clone();
|
||||
byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[]) State.BAK.Clone();
|
||||
Array.Copy(newSAV, 0, newFile, SLOT_START + (SaveIndex * SLOT_SIZE), newSAV.Length);
|
||||
return newFile;
|
||||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone()
|
||||
protected override SaveFile CloneInternal()
|
||||
{
|
||||
var data = GetInnerData();
|
||||
var sav = IsMemoryCardSave ? new SAV3XD(data, MC!) : new SAV3XD(data);
|
||||
sav.Header = (byte[]) Header.Clone();
|
||||
return sav;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ namespace PKHeX.Core
|
|||
/// </remarks>
|
||||
public abstract class SAV4 : SaveFile
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Filter => (Footer.Length > 0 ? "DeSmuME DSV|*.dsv|" : string.Empty) + "SAV File|*.sav|All Files|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Extension => ".sav";
|
||||
|
||||
// Blocks & Offsets
|
||||
|
|
@ -59,16 +58,15 @@ protected SAV4(byte[] data) : base(data)
|
|||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone()
|
||||
protected override SaveFile CloneInternal()
|
||||
{
|
||||
var sav = CloneInternal();
|
||||
var sav = CloneInternal4();
|
||||
SetData(sav.General, General, 0);
|
||||
SetData(sav.Storage, Storage, 0);
|
||||
sav.Footer = (byte[])Footer.Clone();
|
||||
return sav;
|
||||
}
|
||||
|
||||
protected abstract SAV4 CloneInternal();
|
||||
protected abstract SAV4 CloneInternal4();
|
||||
|
||||
public override void CopyChangesFrom(SaveFile sav)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV4BR : SaveFile
|
||||
{
|
||||
protected override string BAKText => $"{Version} #{SaveCount:0000}";
|
||||
public override string Filter => "PbrSaveData|*";
|
||||
protected internal override string ShortSummary => $"{Version} #{SaveCount:0000}";
|
||||
public override string Extension => string.Empty;
|
||||
public override PersonalTable Personal => PersonalTable.DP;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_DP;
|
||||
|
|
@ -67,7 +66,7 @@ protected override byte[] GetFinalData()
|
|||
}
|
||||
|
||||
// Configuration
|
||||
public override SaveFile Clone() => new SAV4BR(Write());
|
||||
protected override SaveFile CloneInternal() => new SAV4BR(Write());
|
||||
|
||||
public readonly List<int> SaveSlots = new List<int>(SAVE_COUNT);
|
||||
public readonly List<string> SaveNames = new List<string>(SAVE_COUNT);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public sealed class SAV4DP : SAV4Sinnoh
|
|||
{
|
||||
public SAV4DP() => Initialize();
|
||||
public SAV4DP(byte[] data) : base(data) => Initialize();
|
||||
protected override SAV4 CloneInternal() => Exportable ? new SAV4DP(Data) : new SAV4DP();
|
||||
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4DP(Data) : new SAV4DP();
|
||||
public override PersonalTable Personal => PersonalTable.DP;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_DP;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public sealed class SAV4HGSS : SAV4
|
|||
{
|
||||
public SAV4HGSS() => Initialize();
|
||||
public SAV4HGSS(byte[] data) : base(data) => Initialize();
|
||||
protected override SAV4 CloneInternal() => Exportable ? new SAV4HGSS(Data) : new SAV4HGSS();
|
||||
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4HGSS(Data) : new SAV4HGSS();
|
||||
|
||||
public override PersonalTable Personal => PersonalTable.HGSS;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_HGSS;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public sealed class SAV4Pt : SAV4Sinnoh
|
|||
{
|
||||
public SAV4Pt() => Initialize();
|
||||
public SAV4Pt(byte[] data) : base(data) => Initialize();
|
||||
protected override SAV4 CloneInternal() => Exportable ? new SAV4Pt(Data) : new SAV4Pt();
|
||||
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4Pt(Data) : new SAV4Pt();
|
||||
public override PersonalTable Personal => PersonalTable.Pt;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_Pt;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ public abstract class SAV5 : SaveFile, ISaveBlock5BW
|
|||
protected override PKM GetPKM(byte[] data) => new PK5(data);
|
||||
protected override byte[] DecryptPKM(byte[] data) => PokeCrypto.DecryptArray45(data);
|
||||
|
||||
protected override string BAKText => $"{OT} ({(GameVersion)Game}) - {PlayTimeString}";
|
||||
public override string Filter => (Footer.Length != 0 ? "DeSmuME DSV|*.dsv|" : string.Empty) + "SAV File|*.sav|All Files|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({(GameVersion)Game}) - {PlayTimeString}";
|
||||
public override string Extension => ".sav";
|
||||
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_BW;
|
||||
|
|
@ -185,7 +184,7 @@ public byte[] CGearSkinData
|
|||
chkbytes.CopyTo(Data, CGearSkinInfoOffset);
|
||||
CGearSkinPresent = true;
|
||||
|
||||
Edited = true;
|
||||
State.Edited = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public SAV5B2W2(byte[] data) : base(data)
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.B2W2;
|
||||
public SaveBlockAccessor5B2W2 Blocks { get; }
|
||||
public override SaveFile Clone() => new SAV5B2W2((byte[])Data.Clone()) { Footer = (byte[])Footer.Clone() };
|
||||
protected override SaveFile CloneInternal() => new SAV5B2W2((byte[]) Data.Clone());
|
||||
protected override int EventConstMax => 0x1AF; // this doesn't seem right?
|
||||
protected override int EventFlagMax => 0xBF8;
|
||||
public override int MaxItemID => Legal.MaxItemID_5_B2W2;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public SAV5BW(byte[] data) : base(data)
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.BW;
|
||||
public SaveBlockAccessor5BW Blocks { get; }
|
||||
public override SaveFile Clone() => new SAV5BW((byte[])Data.Clone()) { Footer = (byte[])Footer.Clone() };
|
||||
protected override SaveFile CloneInternal() => new SAV5BW((byte[])Data.Clone());
|
||||
protected override int EventConstMax => 0x13E;
|
||||
protected override int EventFlagMax => 0xB60;
|
||||
public override int MaxItemID => Legal.MaxItemID_5_BW;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ namespace PKHeX.Core
|
|||
public abstract class SAV6 : SAV_BEEF, ITrainerStatRecord, ISaveBlock6Core, IRegionOrigin, IGameSync
|
||||
{
|
||||
// Save Data Attributes
|
||||
protected override string BAKText => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||
public override string Filter => "Main SAV|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||
public override string Extension => string.Empty;
|
||||
|
||||
protected SAV6(byte[] data, int biOffset) : base(data, biOffset) { }
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public SAV6AO() : base(SaveUtil.SIZE_G6ORAS, SaveBlockAccessor6AO.boAO)
|
|||
public override PersonalTable Personal => PersonalTable.AO;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItem_AO;
|
||||
public SaveBlockAccessor6AO Blocks { get; }
|
||||
public override SaveFile Clone() => new SAV6AO((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV6AO((byte[])Data.Clone());
|
||||
public override int MaxMoveID => Legal.MaxMoveID_6_AO;
|
||||
public override int MaxItemID => Legal.MaxItemID_6_AO;
|
||||
public override int MaxAbilityID => Legal.MaxAbilityID_6_AO;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public SAV6AODemo() : base(SaveUtil.SIZE_G6ORASDEMO, SaveBlockAccessor6AODemo.bo
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.AO;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItem_AO;
|
||||
public override SaveFile Clone() => new SAV6AODemo((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV6AODemo((byte[])Data.Clone());
|
||||
public override int MaxMoveID => Legal.MaxMoveID_6_AO;
|
||||
public override int MaxItemID => Legal.MaxItemID_6_AO;
|
||||
public override int MaxAbilityID => Legal.MaxAbilityID_6_AO;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public SAV6XY() : base(SaveUtil.SIZE_G6XY, SaveBlockAccessor6XY.boXY)
|
|||
public override PersonalTable Personal => PersonalTable.XY;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItem_XY;
|
||||
public SaveBlockAccessor6XY Blocks { get; }
|
||||
public override SaveFile Clone() => new SAV6XY((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV6XY((byte[])Data.Clone());
|
||||
public override int MaxMoveID => Legal.MaxMoveID_6_XY;
|
||||
public override int MaxItemID => Legal.MaxItemID_6_XY;
|
||||
public override int MaxAbilityID => Legal.MaxAbilityID_6_XY;
|
||||
|
|
@ -133,7 +133,8 @@ public void UnlockAllFriendSafariSlots()
|
|||
if (Data[ofs] != 0) // no friend data == 0x00
|
||||
Data[ofs] = 0x3D;
|
||||
}
|
||||
Edited = true;
|
||||
|
||||
State.Edited = true;
|
||||
}
|
||||
|
||||
public override GameVersion Version
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ namespace PKHeX.Core
|
|||
public abstract class SAV7 : SAV_BEEF, ITrainerStatRecord, ISaveBlock7Main, IRegionOrigin
|
||||
{
|
||||
// Save Data Attributes
|
||||
protected override string BAKText => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||
public override string Filter => "Main SAV|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||
public override string Extension => string.Empty;
|
||||
|
||||
public override IReadOnlyList<string> PKMExtensions => PKM.Extensions.Where(f =>
|
||||
|
|
@ -32,7 +31,7 @@ protected SAV7(int size, int biOffset) : base(size, biOffset)
|
|||
protected void ReloadBattleTeams()
|
||||
{
|
||||
var demo = this is SAV7SM && Data.IsRangeAll((byte)0, BoxLayout.Offset, 0x4C4); // up to Battle Box values
|
||||
if (demo || !Exportable)
|
||||
if (demo || !State.Exportable)
|
||||
{
|
||||
BoxLayout.ClearBattleTeams();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ private void Initialize()
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.SM;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_SM;
|
||||
public override SaveFile Clone() => new SAV7SM((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV7SM((byte[])Data.Clone());
|
||||
|
||||
#region Blocks
|
||||
public SaveBlockAccessor7SM Blocks { get; }
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ private void Initialize()
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.USUM;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_USUM;
|
||||
public override SaveFile Clone() => new SAV7USUM((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV7USUM((byte[])Data.Clone());
|
||||
protected override int EventFlagMax => 4928;
|
||||
public override int MaxMoveID => Legal.MaxMoveID_7_USUM;
|
||||
public override int MaxSpeciesID => Legal.MaxSpeciesID_7_USUM;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV7b : SAV_BEEF, IGameSync
|
||||
{
|
||||
protected override string BAKText => $"{OT} ({Version}) - {Blocks.Played.LastSavedTime}";
|
||||
public override string Filter => "savedata|*.bin";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {Blocks.Played.LastSavedTime}";
|
||||
public override string Extension => ".bin";
|
||||
public override IReadOnlyList<string> PKMExtensions => PKM.Extensions.Where(f => f[1] == 'b' && f[f.Length - 1] == '7').ToArray();
|
||||
|
||||
|
|
@ -24,7 +23,7 @@ public sealed class SAV7b : SAV_BEEF, IGameSync
|
|||
public override PersonalTable Personal => PersonalTable.GG;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_GG;
|
||||
|
||||
public override SaveFile Clone() => new SAV7b((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV7b((byte[])Data.Clone());
|
||||
|
||||
public SaveBlockAccessor7b Blocks { get; }
|
||||
public override IReadOnlyList<BlockInfo> AllBlocks => Blocks.BlockInfo;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ namespace PKHeX.Core
|
|||
public abstract class SAV8 : SaveFile, ISaveBlock8Main
|
||||
{
|
||||
// Save Data Attributes
|
||||
protected override string BAKText => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||
public override string Filter => "Main SAV|*.*";
|
||||
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||
public override string Extension => string.Empty;
|
||||
|
||||
public override IReadOnlyList<string> PKMExtensions => PKM.Extensions.Where(f =>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public override void CopyChangesFrom(SaveFile sav)
|
|||
var newB = z.AllBlocks;
|
||||
for (int i = 0; i < mine.Count; i++)
|
||||
newB[i].Data.CopyTo(mine[i].Data, 0);
|
||||
Edited = true;
|
||||
State.Edited = true;
|
||||
}
|
||||
|
||||
public int SaveRevision { get; }
|
||||
|
|
@ -83,7 +83,7 @@ public override void CopyChangesFrom(SaveFile sav)
|
|||
|
||||
public T GetValue<T>(uint key) where T : struct
|
||||
{
|
||||
if (!Exportable)
|
||||
if (!State.Exportable)
|
||||
return default;
|
||||
var value = Blocks.GetBlockValue(key);
|
||||
if (value is T v)
|
||||
|
|
@ -93,13 +93,13 @@ public override void CopyChangesFrom(SaveFile sav)
|
|||
|
||||
public void SetValue<T>(uint key, T value) where T : struct
|
||||
{
|
||||
if (!Exportable)
|
||||
if (!State.Exportable)
|
||||
return;
|
||||
Blocks.SetBlockValue(key, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
public override SaveFile Clone() => new SAV8SWSH(BAK, AllBlocks.Select(z => z.Clone()).ToArray());
|
||||
protected override SaveFile CloneInternal() => new SAV8SWSH(State.BAK, AllBlocks.Select(z => z.Clone()).ToArray());
|
||||
|
||||
private int m_spec, m_item, m_move, m_abil;
|
||||
public override int MaxMoveID => m_move;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
/// </summary>
|
||||
public abstract class SAV_STADIUM : SaveFile, ILangDeviantSave
|
||||
{
|
||||
protected sealed override string BAKText => $"{OT} ({Version})";
|
||||
public sealed override string Filter => "SAV File|*.sav|All Files|*.*";
|
||||
protected internal sealed override string ShortSummary => $"{OT} ({Version})";
|
||||
public sealed override string Extension => ".sav";
|
||||
|
||||
public abstract int SaveRevision { get; }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,19 @@
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public class SaveFileState
|
||||
{
|
||||
public bool Edited { get; set; }
|
||||
public readonly bool Exportable;
|
||||
public readonly byte[] BAK;
|
||||
|
||||
public SaveFileState(byte[] bak, bool exportable = true)
|
||||
{
|
||||
BAK = bak;
|
||||
Exportable = exportable;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base Class for Save Files
|
||||
/// </summary>
|
||||
|
|
@ -12,42 +25,42 @@ public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IBoxDetailWallpa
|
|||
{
|
||||
// General Object Properties
|
||||
public byte[] Data;
|
||||
public bool Edited;
|
||||
public readonly bool Exportable;
|
||||
public readonly byte[] BAK;
|
||||
|
||||
public SaveFileState State { get; }
|
||||
public SaveFileMetadata Metadata { get; private set; }
|
||||
|
||||
protected SaveFile(byte[] data, byte[] bak, bool exportable = true)
|
||||
{
|
||||
Data = data;
|
||||
BAK = bak;
|
||||
Exportable = exportable;
|
||||
State = new SaveFileState(bak, exportable);
|
||||
Metadata = new SaveFileMetadata(this);
|
||||
}
|
||||
|
||||
protected SaveFile(byte[] data, bool exportable = true) : this(data, (byte[])data.Clone(), exportable) { }
|
||||
|
||||
protected SaveFile()
|
||||
protected SaveFile(byte[] data, bool exportable = true) : this(data, (byte[])data.Clone(), exportable)
|
||||
{
|
||||
Data = BAK = Array.Empty<byte>();
|
||||
Exportable = false;
|
||||
}
|
||||
|
||||
protected SaveFile(int size)
|
||||
protected SaveFile(int size = 0)
|
||||
{
|
||||
Data = new byte[size];
|
||||
BAK = Data;
|
||||
Exportable = false;
|
||||
Data = size == 0 ? Array.Empty<byte>() : new byte[size];
|
||||
State = new SaveFileState(Array.Empty<byte>(), false);
|
||||
Metadata = new SaveFileMetadata(this);
|
||||
}
|
||||
|
||||
public string? FileName, FilePath, FileFolder;
|
||||
public string BAKName => $"{FileName} [{BAKText}].bak";
|
||||
protected abstract string BAKText { get; }
|
||||
public abstract SaveFile Clone();
|
||||
public abstract string Filter { get; }
|
||||
public byte[] Footer { protected get; set; } = Array.Empty<byte>(); // .dsv
|
||||
public byte[] Header { protected get; set; } = Array.Empty<byte>(); // .gci
|
||||
public virtual string PlayTimeString => $"{PlayedHours}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
|
||||
protected internal abstract string ShortSummary { get; }
|
||||
public abstract string Extension { get; }
|
||||
|
||||
protected abstract SaveFile CloneInternal();
|
||||
|
||||
public SaveFile Clone()
|
||||
{
|
||||
var sav = CloneInternal();
|
||||
sav.Metadata = Metadata;
|
||||
return sav;
|
||||
}
|
||||
|
||||
public virtual string PlayTimeString => $"{PlayedHours}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
|
||||
|
||||
public virtual IReadOnlyList<string> PKMExtensions => PKM.Extensions.Where(f =>
|
||||
{
|
||||
int gen = f.Last() - 0x30;
|
||||
|
|
@ -58,11 +71,7 @@ protected SaveFile(int size)
|
|||
public byte[] Write(ExportFlags flags = ExportFlags.None)
|
||||
{
|
||||
byte[] data = GetFinalData();
|
||||
if (Footer.Length > 0 && flags.HasFlagFast(ExportFlags.IncludeFooter))
|
||||
return data.Concat(Footer).ToArray();
|
||||
if (Header.Length > 0 && flags.HasFlagFast(ExportFlags.IncludeHeader))
|
||||
return Header.Concat(data).ToArray();
|
||||
return data;
|
||||
return Metadata.Finalize(data, flags);
|
||||
}
|
||||
|
||||
protected virtual byte[] GetFinalData()
|
||||
|
|
@ -87,7 +96,7 @@ protected virtual byte[] GetFinalData()
|
|||
public void SetData(byte[] dest, byte[] input, int offset)
|
||||
{
|
||||
input.CopyTo(dest, offset);
|
||||
Edited = true;
|
||||
State.Edited = true;
|
||||
}
|
||||
|
||||
public abstract string GetString(byte[] data, int offset, int length);
|
||||
|
|
|
|||
78
PKHeX.Core/Saves/SaveFileMetadata.cs
Normal file
78
PKHeX.Core/Saves/SaveFileMetadata.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public class SaveFileMetadata
|
||||
{
|
||||
private readonly SaveFile SAV;
|
||||
|
||||
public string? FileName;
|
||||
public string? FilePath;
|
||||
public string? FileFolder;
|
||||
private byte[] Footer = Array.Empty<byte>(); // .dsv
|
||||
private byte[] Header = Array.Empty<byte>(); // .gci
|
||||
|
||||
public string BAKName => $"{FileName} [{SAV.ShortSummary}].bak";
|
||||
|
||||
public SaveFileMetadata(SaveFile sav) => SAV = sav;
|
||||
|
||||
public bool HasHeader => Header.Length != 0;
|
||||
public bool HasFooter => Footer.Length != 0;
|
||||
public string Filter => $"{SAV.GetType().Name}|{GetSuggestedExtension()}|All Files|*.*";
|
||||
|
||||
public byte[] Finalize(byte[] data, ExportFlags flags)
|
||||
{
|
||||
if (Footer.Length > 0 && flags.HasFlagFast(ExportFlags.IncludeFooter))
|
||||
return data.Concat(Footer).ToArray();
|
||||
if (Header.Length > 0 && flags.HasFlagFast(ExportFlags.IncludeHeader))
|
||||
return Header.Concat(data).ToArray();
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the details of any trimmed header and footer arrays to a <see cref="SaveFile"/> object.
|
||||
/// </summary>
|
||||
public void SetExtraInfo(byte[] header, byte[] footer)
|
||||
{
|
||||
Header = header;
|
||||
Footer = footer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the details of a path to a <see cref="SaveFile"/> object.
|
||||
/// </summary>
|
||||
/// <param name="path">Full Path of the file</param>
|
||||
public void SetExtraInfo(string path)
|
||||
{
|
||||
var sav = SAV;
|
||||
if (!sav.State.Exportable) // Blank save file
|
||||
{
|
||||
sav.Metadata.FileFolder = sav.Metadata.FilePath = string.Empty;
|
||||
sav.Metadata.FileName = "Blank Save File";
|
||||
return;
|
||||
}
|
||||
|
||||
sav.Metadata.FilePath = path;
|
||||
sav.Metadata.FileFolder = Path.GetDirectoryName(path);
|
||||
sav.Metadata.FileName = string.Empty;
|
||||
var bakName = Util.CleanFileName(sav.Metadata.BAKName);
|
||||
sav.Metadata.FileName = Path.GetFileName(path);
|
||||
if (sav.Metadata.FileName?.EndsWith(bakName) == true)
|
||||
sav.Metadata.FileName = sav.Metadata.FileName.Substring(0, sav.Metadata.FileName.Length - bakName.Length);
|
||||
}
|
||||
|
||||
public string GetSuggestedExtension()
|
||||
{
|
||||
var sav = SAV;
|
||||
var fn = sav.Metadata.FileName;
|
||||
if (fn != null)
|
||||
return Path.GetExtension(fn);
|
||||
|
||||
if ((sav.Generation == 4 || sav.Generation == 5) && sav.Metadata.HasFooter)
|
||||
return ".dsv";
|
||||
return sav.Extension;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,11 +11,10 @@ public sealed class Bank3 : BulkStorage
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.RS;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_RS;
|
||||
public override SaveFile Clone() => new Bank3((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new Bank3((byte[])Data.Clone());
|
||||
public override string PlayTimeString => Checksums.CRC16(Data, 0, Data.Length).ToString("X4");
|
||||
protected override string BAKText => PlayTimeString;
|
||||
protected internal override string ShortSummary => PlayTimeString;
|
||||
public override string Extension => ".gst";
|
||||
public override string Filter { get; } = "PokeStock G3 Storage|*.gst*";
|
||||
|
||||
public override int BoxCount => 64;
|
||||
private const int BoxNameSize = 9;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,10 @@ public sealed class Bank4 : BulkStorage
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.HGSS;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_HGSS;
|
||||
public override SaveFile Clone() => new Bank4((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new Bank4((byte[])Data.Clone());
|
||||
public override string PlayTimeString => Checksums.CRC16(Data, 0, Data.Length).ToString("X4");
|
||||
protected override string BAKText => PlayTimeString;
|
||||
protected internal override string ShortSummary => PlayTimeString;
|
||||
public override string Extension => ".stk";
|
||||
public override string Filter { get; } = "PokeStock G4 Storage|*.stk*";
|
||||
|
||||
public override int BoxCount => 64;
|
||||
private const int BoxNameSize = 0x18;
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ public sealed class Bank7 : BulkStorage
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.USUM;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_SM;
|
||||
public override SaveFile Clone() => new Bank7((byte[])Data.Clone(), PKMType, BoxStart, SlotsPerBox);
|
||||
protected override SaveFile CloneInternal() => new Bank7((byte[])Data.Clone(), PKMType, BoxStart, SlotsPerBox);
|
||||
public override string PlayTimeString => $"{Year:00}{Month:00}{Day:00}_{Hours:00}ː{Minutes:00}";
|
||||
protected override string BAKText => PlayTimeString;
|
||||
protected internal override string ShortSummary => PlayTimeString;
|
||||
private const int GroupNameSize = 0x20;
|
||||
private const int BankNameSize = 0x24;
|
||||
private const int GroupNameSpacing = GroupNameSize + 2;
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@ protected BulkStorage(byte[] data, Type t, int start, int slotsPerBox = 30) : ba
|
|||
|
||||
protected readonly int SlotsPerBox;
|
||||
|
||||
protected override string BAKText => $"{Checksums.CRC16(Data, Box, Data.Length - Box):X4}";
|
||||
public override string Filter { get; } = "All Files|*.*";
|
||||
public override string Extension { get; } = ".bin";
|
||||
public sealed override bool ChecksumsValid { get; } = true;
|
||||
public sealed override string ChecksumInfo { get; } = "No Info.";
|
||||
protected internal override string ShortSummary => $"{Checksums.CRC16(Data, Box, Data.Length - Box):X4}";
|
||||
public override string Extension => ".bin";
|
||||
public sealed override bool ChecksumsValid => true;
|
||||
public sealed override string ChecksumInfo => "No Info.";
|
||||
|
||||
private readonly PKM blank;
|
||||
public sealed override Type PKMType => blank.GetType();
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@ public sealed class SAV4Ranch : BulkStorage, ISaveFileRevision
|
|||
|
||||
public override PersonalTable Personal => PersonalTable.Pt;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_Pt;
|
||||
public override SaveFile Clone() => new SAV4Ranch((byte[])Data.Clone());
|
||||
protected override SaveFile CloneInternal() => new SAV4Ranch((byte[])Data.Clone());
|
||||
public override string PlayTimeString => Checksums.CRC16(Data, 0, Data.Length).ToString("X4");
|
||||
protected override string BAKText => $"{OT} {PlayTimeString}";
|
||||
protected internal override string ShortSummary => $"{OT} {PlayTimeString}";
|
||||
public override string Extension => ".bin";
|
||||
public override string Filter { get; } = "Ranch G4 Storage|*.bin*";
|
||||
|
||||
protected override PKM GetPKM(byte[] data) => new PK4(data);
|
||||
protected override byte[] DecryptPKM(byte[] data) => PokeCrypto.DecryptArray45(data);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public void SetReceivedFlags(bool[] value)
|
|||
if (value.Length != MaxReceivedFlag)
|
||||
return;
|
||||
ArrayUtil.SetBitFlagArray(Data, Offset + FlagStart, value);
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
|
||||
public DataMysteryGift[] GetGifts()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public bool[] MysteryGiftReceivedFlags
|
|||
if (value.Length != MaxReceivedFlag)
|
||||
return;
|
||||
ArrayUtil.SetBitFlagArray(Data, Offset + FlagStart, value);
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public PokeListHeader(SAV7b sav, int offset) : base(sav)
|
|||
{
|
||||
Offset = offset;
|
||||
PokeListInfo = LoadPointerData();
|
||||
if (!sav.Exportable)
|
||||
if (!sav.State.Exportable)
|
||||
{
|
||||
for (int i = 0; i < COUNT; i++)
|
||||
PokeListInfo[i] = SLOT_EMPTY;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public string Number
|
|||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
Data[0x01 + i] = (byte)(value.Length > i ? value[i] : '\0');
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public sealed class TeamIndexes8 : SaveBlock, ITeamIndexSet
|
|||
|
||||
public void LoadBattleTeams()
|
||||
{
|
||||
if (!SAV.Exportable)
|
||||
if (!SAV.State.Exportable)
|
||||
{
|
||||
ClearBattleTeams();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public string Number
|
|||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
Data[0x39 + i] = (byte) (value.Length > i ? value[i] : '\0');
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ private Zukan7(SaveFile sav, int dex, int langflag, Func<int, int, int, int> for
|
|||
{
|
||||
DexFormIndexFetcher = form;
|
||||
FormBaseSpecies = GetFormIndexBaseSpeciesList();
|
||||
Debug.Assert(!SAV.Exportable || BitConverter.ToUInt32(SAV.Data, PokeDex) == MAGIC);
|
||||
Debug.Assert(!SAV.State.Exportable || BitConverter.ToUInt32(SAV.Data, PokeDex) == MAGIC);
|
||||
}
|
||||
|
||||
public Func<int, int, int, int> DexFormIndexFetcher { get; }
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ public static string[] GetBoxNames(SaveFile sav)
|
|||
{
|
||||
int count = sav.BoxCount;
|
||||
var result = new string[count];
|
||||
if (!sav.Exportable)
|
||||
if (!sav.State.Exportable)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
result[i] = $"Box {i + 1}";
|
||||
|
|
|
|||
|
|
@ -22,30 +22,7 @@ public static class SaveExtensions
|
|||
/// <param name="pk">PKM input that is to be injected into the Save File.</param>
|
||||
/// <returns>Indication whether or not the PKM is compatible.</returns>
|
||||
public static bool IsPKMCompatibleWithModifications(this SaveFile sav, PKM pk) => PKMConverter.IsPKMCompatibleWithModifications(pk, sav);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the details of a path to a <see cref="SaveFile"/> object.
|
||||
/// </summary>
|
||||
/// <param name="sav">Save File to set path details to.</param>
|
||||
/// <param name="path">Full Path of the file</param>
|
||||
public static void SetFileInfo(this SaveFile sav, string path)
|
||||
{
|
||||
if (!sav.Exportable) // Blank save file
|
||||
{
|
||||
sav.FileFolder = sav.FilePath = string.Empty;
|
||||
sav.FileName = "Blank Save File";
|
||||
return;
|
||||
}
|
||||
|
||||
sav.FilePath = path;
|
||||
sav.FileFolder = Path.GetDirectoryName(path);
|
||||
sav.FileName = string.Empty;
|
||||
var bakName = Util.CleanFileName(sav.BAKName);
|
||||
sav.FileName = Path.GetFileName(path);
|
||||
if (sav.FileName?.EndsWith(bakName) == true)
|
||||
sav.FileName = sav.FileName.Substring(0, sav.FileName.Length - bakName.Length);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets suggested export options for the save file.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public static bool DetectSaveFile(out string path, out SaveFile? sav, IReadOnlyL
|
|||
return false;
|
||||
}
|
||||
|
||||
path = result.FilePath!;
|
||||
path = result.Metadata.FilePath!;
|
||||
sav = result;
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ private static GameVersion GetIsG8SAV(byte[] data)
|
|||
var sav = GetVariantSAV(data);
|
||||
if (sav == null)
|
||||
return null;
|
||||
sav.SetFileInfo(path);
|
||||
sav.Metadata.SetExtraInfo(path);
|
||||
return sav;
|
||||
}
|
||||
|
||||
|
|
@ -501,8 +501,8 @@ private static GameVersion GetIsG8SAV(byte[] data)
|
|||
var sav = GetVariantSAVInternal(data);
|
||||
if (sav == null)
|
||||
return null;
|
||||
sav.Header = header;
|
||||
sav.Footer = footer;
|
||||
|
||||
sav.Metadata.SetExtraInfo(header, footer);
|
||||
return sav;
|
||||
}
|
||||
|
||||
|
|
@ -569,8 +569,8 @@ private static GameVersion GetIsG8SAV(byte[] data)
|
|||
// No pattern matched
|
||||
default: return null;
|
||||
}
|
||||
sav.Header = header;
|
||||
sav.Footer = footer;
|
||||
|
||||
sav.Metadata.SetExtraInfo(header, footer);
|
||||
return sav;
|
||||
}
|
||||
|
||||
|
|
@ -780,12 +780,9 @@ private static void CheckHeaderFooter(ref byte[] input, out byte[] header, out b
|
|||
input = input.SliceEnd(0xA4);
|
||||
return;
|
||||
}
|
||||
int start = input.Length - FOOTER_DSV.Length;
|
||||
for (int i = 0; i < FOOTER_DSV.Length; i++)
|
||||
{
|
||||
if (FOOTER_DSV[i] != input[start + i])
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetHasFooterDSV(input))
|
||||
return;
|
||||
|
||||
footer = input.SliceEnd(SIZE_G4RAW);
|
||||
input = input.Slice(0, SIZE_G4RAW);
|
||||
|
|
@ -814,6 +811,24 @@ private static void CheckHeaderFooter(ref byte[] input, out byte[] header, out b
|
|||
static bool IsGameMatchHeader(IEnumerable<string> headers, byte[] data) => headers.Contains(Encoding.ASCII.GetString(data, 0, 4));
|
||||
}
|
||||
|
||||
private static bool GetHasFooterDSV(byte[] input)
|
||||
{
|
||||
var signature = FOOTER_DSV;
|
||||
if (!GetHasSignature(input, signature, input.Length - signature.Length))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool GetHasSignature(byte[] input, byte[] signature, int start)
|
||||
{
|
||||
for (int i = 0; i < signature.Length; i++)
|
||||
{
|
||||
if (signature[i] != input[start + i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force loads the provided <see cref="sav"/> to the requested <see cref="ver"/>.
|
||||
/// </summary>
|
||||
|
|
@ -824,13 +839,13 @@ public static SAV3 GetG3SaveOverride(SaveFile sav, GameVersion ver)
|
|||
{
|
||||
return ver switch // Reset save file info
|
||||
{
|
||||
R => new SAV3(sav.BAK, RS),
|
||||
S => new SAV3(sav.BAK, RS),
|
||||
RS => new SAV3(sav.BAK, RS),
|
||||
E => new SAV3(sav.BAK, E),
|
||||
FRLG => new SAV3(sav.BAK, FRLG),
|
||||
FR => new SAV3(sav.BAK, FRLG),
|
||||
LG => new SAV3(sav.BAK, FRLG),
|
||||
R => new SAV3(sav.State.BAK, RS),
|
||||
S => new SAV3(sav.State.BAK, RS),
|
||||
RS => new SAV3(sav.State.BAK, RS),
|
||||
E => new SAV3(sav.State.BAK, E),
|
||||
FRLG => new SAV3(sav.State.BAK, FRLG),
|
||||
FR => new SAV3(sav.State.BAK, FRLG),
|
||||
LG => new SAV3(sav.State.BAK, FRLG),
|
||||
_ => throw new ArgumentException(nameof(ver))
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,13 +456,13 @@ private void UpdateStringSeed(object sender, EventArgs e)
|
|||
{
|
||||
var value = filterText.PadLeft(SAV.DaycareSeedSize, '0');
|
||||
SAV.SetDaycareRNGSeed(SAV.DaycareIndex, value);
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
else if (tb == TB_GameSync && SAV is IGameSync sync)
|
||||
{
|
||||
var value = filterText.PadLeft(sync.GameSyncIDSize, '0');
|
||||
sync.GameSyncID = value;
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
else if (SAV is ISecureValueStorage s)
|
||||
{
|
||||
|
|
@ -471,7 +471,7 @@ private void UpdateStringSeed(object sender, EventArgs e)
|
|||
s.TimeStampCurrent = value;
|
||||
else if (tb == TB_Secure2)
|
||||
s.TimeStampPrevious = value;
|
||||
SAV.Edited = true;
|
||||
SAV.State.Edited = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -728,7 +728,7 @@ private void ClickVerifyCHK(object sender, EventArgs e)
|
|||
return;
|
||||
}
|
||||
|
||||
if (SAV.Edited)
|
||||
if (SAV.State.Edited)
|
||||
{
|
||||
WinFormsUtil.Alert(MsgSaveChecksumFailEdited);
|
||||
return;
|
||||
|
|
@ -775,14 +775,14 @@ public bool ExportSaveFile()
|
|||
|
||||
public bool ExportBackup()
|
||||
{
|
||||
if (!SAV.Exportable)
|
||||
if (!SAV.State.Exportable)
|
||||
return false;
|
||||
using var sfd = new SaveFileDialog {FileName = Util.CleanFileName(SAV.BAKName)};
|
||||
using var sfd = new SaveFileDialog {FileName = Util.CleanFileName(SAV.Metadata.BAKName)};
|
||||
if (sfd.ShowDialog() != DialogResult.OK)
|
||||
return false;
|
||||
|
||||
string path = sfd.FileName;
|
||||
File.WriteAllBytes(path, SAV.BAK);
|
||||
File.WriteAllBytes(path, SAV.State.BAK);
|
||||
WinFormsUtil.Alert(MsgSaveBackup, path);
|
||||
|
||||
return true;
|
||||
|
|
@ -1009,7 +1009,7 @@ private bool ToggleViewBox(SaveFile sav)
|
|||
|
||||
private bool ToggleViewParty(SaveFile sav, int BoxTab)
|
||||
{
|
||||
if (!sav.HasParty || !sav.Exportable)
|
||||
if (!sav.HasParty || !sav.State.Exportable)
|
||||
{
|
||||
if (tabBoxMulti.TabPages.Contains(Tab_PartyBattle))
|
||||
tabBoxMulti.TabPages.Remove(Tab_PartyBattle);
|
||||
|
|
@ -1028,7 +1028,7 @@ private bool ToggleViewParty(SaveFile sav, int BoxTab)
|
|||
|
||||
private bool ToggleViewDaycare(SaveFile sav, int BoxTab, int PartyTab)
|
||||
{
|
||||
if ((!sav.HasDaycare && SL_Extra.SlotCount == 0) || !sav.Exportable)
|
||||
if ((!sav.HasDaycare && SL_Extra.SlotCount == 0) || !sav.State.Exportable)
|
||||
{
|
||||
if (tabBoxMulti.TabPages.Contains(Tab_Other))
|
||||
tabBoxMulti.TabPages.Remove(Tab_Other);
|
||||
|
|
@ -1050,7 +1050,7 @@ private bool ToggleViewDaycare(SaveFile sav, int BoxTab, int PartyTab)
|
|||
|
||||
private void ToggleViewSubEditors(SaveFile sav)
|
||||
{
|
||||
if (!sav.Exportable || sav is BulkStorage)
|
||||
if (!sav.State.Exportable || sav is BulkStorage)
|
||||
{
|
||||
GB_SAVtools.Visible = false;
|
||||
B_JPEG.Visible = false;
|
||||
|
|
@ -1093,7 +1093,7 @@ private void ToggleViewSubEditors(SaveFile sav)
|
|||
SL_Extra.SAV = sav;
|
||||
SL_Extra.Initialize(sav.GetExtraSlots(HaX), InitializeDragDrop);
|
||||
}
|
||||
GB_SAVtools.Visible = sav.Exportable && FLP_SAVtools.Controls.OfType<Control>().Any(c => c.Enabled);
|
||||
GB_SAVtools.Visible = sav.State.Exportable && FLP_SAVtools.Controls.OfType<Control>().Any(c => c.Enabled);
|
||||
foreach (Control c in FLP_SAVtools.Controls.OfType<Control>())
|
||||
c.Visible = c.Enabled;
|
||||
var list = FLP_SAVtools.Controls.OfType<Control>().ToArray();
|
||||
|
|
@ -1106,7 +1106,7 @@ private void ToggleViewMisc(SaveFile sav)
|
|||
{
|
||||
// Generational Interface
|
||||
ToggleSecrets(sav, HideSecretDetails);
|
||||
B_VerifyCHK.Enabled = SAV.Exportable;
|
||||
B_VerifyCHK.Enabled = SAV.State.Exportable;
|
||||
|
||||
if (sav is SAV4BR br)
|
||||
{
|
||||
|
|
@ -1138,7 +1138,7 @@ private void ToggleViewMisc(SaveFile sav)
|
|||
|
||||
private void ToggleSecrets(SaveFile sav, bool hide)
|
||||
{
|
||||
var shouldShow = sav.Exportable && !hide;
|
||||
var shouldShow = sav.State.Exportable && !hide;
|
||||
TB_Secure1.Visible = TB_Secure2.Visible = L_Secure1.Visible = L_Secure2.Visible = shouldShow && sav is ISecureValueStorage;
|
||||
TB_GameSync.Visible = L_GameSync.Visible = shouldShow && sav is IGameSync;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ private void LoadBlankSaveFile(GameVersion ver)
|
|||
if (sav.Version == GameVersion.Invalid) // will fail to load
|
||||
sav = SaveUtil.GetBlankSAV((GameVersion)GameInfo.VersionDataSource.Max(z => z.Value), tr, lang);
|
||||
OpenSAV(sav, string.Empty);
|
||||
C_SAV!.SAV.Edited = false; // Prevents form close warning from showing until changes are made
|
||||
C_SAV!.SAV.State.Edited = false; // Prevents form close warning from showing until changes are made
|
||||
}
|
||||
|
||||
private void FormLoadCheckForUpdates()
|
||||
|
|
@ -486,7 +486,7 @@ private void MainMenuFolder(object sender, EventArgs e)
|
|||
{
|
||||
if (this.OpenWindowExists<SAV_FolderList>())
|
||||
return;
|
||||
var form = new SAV_FolderList(s => OpenSAV(SaveUtil.GetVariantSAV(s.FilePath!), s.FilePath!));
|
||||
var form = new SAV_FolderList(s => OpenSAV(SaveUtil.GetVariantSAV(s.Metadata.FilePath!), s.Metadata.FilePath!));
|
||||
form.Show();
|
||||
}
|
||||
|
||||
|
|
@ -729,11 +729,11 @@ private bool OpenSAV(SaveFile? sav, string path)
|
|||
return true;
|
||||
}
|
||||
|
||||
sav.SetFileInfo(path);
|
||||
sav.Metadata.SetExtraInfo(path);
|
||||
if (!SanityCheckSAV(ref sav))
|
||||
return true;
|
||||
|
||||
if (C_SAV.SAV.Edited && Settings.Default.ModifyUnset)
|
||||
if (C_SAV.SAV.State.Edited && Settings.Default.ModifyUnset)
|
||||
{
|
||||
var prompt = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgProgramCloseUnsaved, MsgProgramSaveFileConfirm);
|
||||
if (prompt != DialogResult.Yes)
|
||||
|
|
@ -747,7 +747,7 @@ private bool OpenSAV(SaveFile? sav, string path)
|
|||
dragout.Size = new Size(SpriteUtil.Spriter.Width, SpriteUtil.Spriter.Height);
|
||||
|
||||
// clean fields
|
||||
Menu_ExportSAV.Enabled = sav.Exportable;
|
||||
Menu_ExportSAV.Enabled = sav.State.Exportable;
|
||||
|
||||
// No changes made yet
|
||||
Menu_Undo.Enabled = false;
|
||||
|
|
@ -807,7 +807,7 @@ private void ResetSAVPKMEditors(SaveFile sav)
|
|||
PKME_Tabs.FlickerInterface();
|
||||
foreach (var p in Plugins)
|
||||
p.NotifySaveLoaded();
|
||||
sav.Edited = false;
|
||||
sav.State.Edited = false;
|
||||
}
|
||||
|
||||
private static string GetProgramTitle()
|
||||
|
|
@ -830,9 +830,9 @@ private static string GetProgramTitle(SaveFile sav)
|
|||
var ver = GameInfo.GetVersionName(sav.Version);
|
||||
if (Settings.Default.HideSAVDetails)
|
||||
return title + $"[{ver}]";
|
||||
if (!sav.Exportable) // Blank save file
|
||||
return title + $"{sav.FileName} [{sav.OT} ({ver})]";
|
||||
return title + Path.GetFileNameWithoutExtension(Util.CleanFileName(sav.BAKName)); // more descriptive
|
||||
if (!sav.State.Exportable) // Blank save file
|
||||
return title + $"{sav.Metadata.FileName} [{sav.OT} ({ver})]";
|
||||
return title + Path.GetFileNameWithoutExtension(Util.CleanFileName(sav.Metadata.BAKName)); // more descriptive
|
||||
}
|
||||
|
||||
private static bool TryBackupExportCheck(SaveFile sav, string path)
|
||||
|
|
@ -841,9 +841,9 @@ private static bool TryBackupExportCheck(SaveFile sav, string path)
|
|||
return false;
|
||||
|
||||
// If backup folder exists, save a backup.
|
||||
string backupName = Path.Combine(BackupPath, Util.CleanFileName(sav.BAKName));
|
||||
if (sav.Exportable && Directory.Exists(BackupPath) && !File.Exists(backupName))
|
||||
File.WriteAllBytes(backupName, sav.BAK);
|
||||
string backupName = Path.Combine(BackupPath, Util.CleanFileName(sav.Metadata.BAKName));
|
||||
if (sav.State.Exportable && Directory.Exists(BackupPath) && !File.Exists(backupName))
|
||||
File.WriteAllBytes(backupName, sav.State.BAK);
|
||||
|
||||
if (!FileUtil.IsFileLocked(path))
|
||||
return true;
|
||||
|
|
@ -856,7 +856,7 @@ private static bool SanityCheckSAV(ref SaveFile sav)
|
|||
{
|
||||
ParseSettings.InitFromSaveFileData(sav); // physical GB, no longer used in logic
|
||||
|
||||
if (sav.Exportable && sav is SAV3 s3)
|
||||
if (sav.State.Exportable && sav is SAV3 s3)
|
||||
{
|
||||
if (s3.IndeterminateGame || ModifierKeys == Keys.Control)
|
||||
{
|
||||
|
|
@ -1156,7 +1156,7 @@ private void DragoutDrop(object sender, DragEventArgs e)
|
|||
|
||||
private void Main_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (C_SAV.SAV.Edited || PKME_Tabs.PKMIsUnsaved)
|
||||
if (C_SAV.SAV.State.Edited || PKME_Tabs.PKMIsUnsaved)
|
||||
{
|
||||
var prompt = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgProgramCloseUnsaved, MsgProgramCloseConfirm);
|
||||
if (prompt != DialogResult.Yes)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace PKHeX.WinForms
|
|||
public partial class SAV_FolderList : Form
|
||||
{
|
||||
private readonly Action<SaveFile> OpenSaveFile;
|
||||
private readonly List<CustomFolderPath> Paths;
|
||||
private readonly List<INamedFolderPath> Paths;
|
||||
private readonly SortableBindingList<SavePreview> Recent;
|
||||
private readonly SortableBindingList<SavePreview> Backup;
|
||||
private readonly List<Label> TempTranslationLabels = new List<Label>();
|
||||
|
|
@ -73,9 +73,9 @@ public SAV_FolderList(Action<SaveFile> openSaveFile)
|
|||
CenterToParent();
|
||||
}
|
||||
|
||||
private static List<CustomFolderPath> GetPathList(IReadOnlyList<string> drives)
|
||||
private static List<INamedFolderPath> GetPathList(IReadOnlyList<string> drives)
|
||||
{
|
||||
var locs = new List<CustomFolderPath>
|
||||
var locs = new List<INamedFolderPath>
|
||||
{
|
||||
new CustomFolderPath(Main.BackupPath, "PKHeX Backups")
|
||||
};
|
||||
|
|
@ -118,7 +118,7 @@ private void AddCustomizeButton()
|
|||
var custom = Paths.Where(z => z.Custom).ToList();
|
||||
if (custom.Count == 0)
|
||||
Paths.Add(new CustomFolderPath("DISPLAY_TEXT", "FOLDER_PATH", true));
|
||||
var lines = custom.Select(z => z.Write());
|
||||
var lines = custom.Select(z => ((CustomFolderPath)z).ToString());
|
||||
File.WriteAllLines(loc, lines);
|
||||
}
|
||||
Process.Start(loc);
|
||||
|
|
@ -173,11 +173,11 @@ private static IEnumerable<CustomFolderPath> GetSwitchPaths(IEnumerable<string>
|
|||
return paths.Select(z => new CustomFolderPath(z));
|
||||
}
|
||||
|
||||
private sealed class CustomFolderPath
|
||||
private sealed class CustomFolderPath : INamedFolderPath
|
||||
{
|
||||
public readonly string Path;
|
||||
public readonly string DisplayText;
|
||||
public readonly bool Custom;
|
||||
public string Path { get; }
|
||||
public string DisplayText { get; }
|
||||
public bool Custom { get; }
|
||||
|
||||
public CustomFolderPath(string z, bool custom = false)
|
||||
{
|
||||
|
|
@ -206,44 +206,11 @@ public CustomFolderPath(string path, string display, bool custom = false)
|
|||
Custom = custom;
|
||||
}
|
||||
|
||||
public string Write() => $"{DisplayText}\t{Path}";
|
||||
}
|
||||
|
||||
private string GetParentFolderName(SaveFile first)
|
||||
{
|
||||
var parent = Paths.Find(z => first.FileFolder?.StartsWith(z.Path) == true);
|
||||
return parent?.DisplayText ?? "???";
|
||||
public override string ToString() => $"{DisplayText}\t{Path}";
|
||||
}
|
||||
|
||||
private sealed class SaveList<T> : SortableBindingList<T> where T : class { }
|
||||
|
||||
private sealed class SavePreview
|
||||
{
|
||||
public readonly SaveFile Save;
|
||||
|
||||
public SavePreview(SaveFile sav, string parent)
|
||||
{
|
||||
Save = sav;
|
||||
Folder = parent;
|
||||
}
|
||||
|
||||
public string OT => Save.OT;
|
||||
public int G => Save.Generation;
|
||||
public GameVersion Game => Save.Version;
|
||||
|
||||
public string Played => Save.PlayTimeString.PadLeft(9, '0');
|
||||
public string FileTime => File.GetLastWriteTimeUtc(Save.FilePath!).ToString("yyyy.MM.dd:hh:mm:ss");
|
||||
|
||||
public string TID => Save.Generation >= 7 ? Save.TrainerID7.ToString("000000") : Save.TID.ToString("00000");
|
||||
public string SID => Save.Generation >= 7 ? Save.TrainerSID7.ToString("0000") : Save.SID.ToString("00000");
|
||||
|
||||
// ReSharper disable once MemberCanBePrivate.Local
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public string Folder { get; }
|
||||
|
||||
public string? Name => Path.GetFileName(Save.FilePath);
|
||||
}
|
||||
|
||||
private ContextMenuStrip GetContextMenu(DataGridView dgv)
|
||||
{
|
||||
var mnuOpen = new ToolStripMenuItem
|
||||
|
|
@ -289,7 +256,7 @@ private void ClickOpenFolder(DataGridView dgv)
|
|||
return;
|
||||
}
|
||||
|
||||
var path = sav.Save.FilePath;
|
||||
var path = sav.Save.Metadata.FilePath;
|
||||
Process.Start("explorer.exe", $"/select, \"{path}\"");
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +294,7 @@ private SaveList<SavePreview> PopulateData(DataGridView dgData, IEnumerable<Save
|
|||
}
|
||||
|
||||
var first = enumerator.Current;
|
||||
var sav1 = new SavePreview(first, GetParentFolderName(first));
|
||||
var sav1 = new SavePreview(first, Paths);
|
||||
LoadEntryInitial(dgData, list, sav1);
|
||||
|
||||
int ctr = 1; // refresh every 7 until 15+ are loaded
|
||||
|
|
@ -338,7 +305,7 @@ private SaveList<SavePreview> PopulateData(DataGridView dgData, IEnumerable<Save
|
|||
while (enumerator.MoveNext())
|
||||
{
|
||||
var next = enumerator.Current;
|
||||
var sav = new SavePreview(next, GetParentFolderName(next));
|
||||
var sav = new SavePreview(next, Paths);
|
||||
dgData.Invoke(new Action(() => LoadEntry(dgData, list, sav)));
|
||||
ctr++;
|
||||
if (ctr < 15 && ctr % 7 == 0)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ private void SaveData()
|
|||
Data.MasterFlag = CHK_Master.Checked;
|
||||
SaveCurrent();
|
||||
Origin.Data = SAV.Data;
|
||||
Origin.Edited = true;
|
||||
Origin.State.Edited = true;
|
||||
}
|
||||
|
||||
private void LoadCurrent()
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ private void B_Cancel_Click(object sender, EventArgs e)
|
|||
private void B_Save_Click(object sender, EventArgs e)
|
||||
{
|
||||
Editor.Save();
|
||||
Origin.Edited = true;
|
||||
Origin.State.Edited = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
|
|
@ -298,14 +298,14 @@ private void B_ApplyFlag_Click(object sender, EventArgs e)
|
|||
{
|
||||
var index = (int)NUD_Flag.Value;
|
||||
SAV.SetFlag(index, c_CustomFlag.Checked);
|
||||
Origin.Edited = true;
|
||||
Origin.State.Edited = true;
|
||||
}
|
||||
|
||||
private void B_ApplyWork_Click(object sender, EventArgs e)
|
||||
{
|
||||
var index = CB_Stats.SelectedIndex;
|
||||
SAV.SetWork(index, (int)NUD_Stat.Value);
|
||||
Origin.Edited = true;
|
||||
Origin.State.Edited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -279,7 +279,7 @@ public static bool OpenSAVPKMDialog(IEnumerable<string> extensions, out string?
|
|||
Error(msg);
|
||||
|
||||
if (sav != null)
|
||||
ofd.FileName = sav.FileName;
|
||||
ofd.FileName = sav.Metadata.FileName;
|
||||
|
||||
if (ofd.ShowDialog() != DialogResult.OK)
|
||||
{
|
||||
|
|
@ -346,13 +346,13 @@ public static bool ExportSAVDialog(SaveFile sav, int currentBox = 0)
|
|||
{
|
||||
using var sfd = new SaveFileDialog
|
||||
{
|
||||
Filter = sav.Filter,
|
||||
FileName = sav.FileName,
|
||||
Filter = sav.Metadata.Filter,
|
||||
FileName = sav.Metadata.FileName,
|
||||
FilterIndex = 1000, // default to last, All Files
|
||||
RestoreDirectory = true
|
||||
};
|
||||
if (Directory.Exists(sav.FileFolder))
|
||||
sfd.InitialDirectory = sav.FileFolder;
|
||||
if (Directory.Exists(sav.Metadata.FileFolder))
|
||||
sfd.InitialDirectory = sav.Metadata.FileFolder;
|
||||
|
||||
if (sfd.ShowDialog() != DialogResult.OK)
|
||||
return false;
|
||||
|
|
@ -377,8 +377,8 @@ private static void ExportSAV(SaveFile sav, string path)
|
|||
try
|
||||
{
|
||||
File.WriteAllBytes(path, sav.Write(flags));
|
||||
sav.Edited = false;
|
||||
sav.SetFileInfo(path);
|
||||
sav.State.Edited = false;
|
||||
sav.Metadata.SetExtraInfo(path);
|
||||
Alert(MsgSaveExportSuccessPath, path);
|
||||
}
|
||||
catch (Exception x)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user