mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-09 02:46:34 -05:00
Add custom save type loading (hacks)
plugin adds a reader -> reader checks if it is a non-PKHeX.Core save type (they'd implement their own savefile/etc type) -> returns a matching save object if so basically bypasses the base PKHeX logic
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
#if !(EXCLUDE_EMULATOR_FORMATS && EXCLUDE_HACKS)
|
||||
/// <summary>
|
||||
/// Provides handling for recognizing atypical save file formats.
|
||||
/// </summary>
|
||||
@@ -19,4 +20,21 @@ public interface ISaveHandler
|
||||
/// <returns>Null if not a valid save file for this handler's format. Returns an object containing header, footer, and inner data references.</returns>
|
||||
SaveHandlerSplitResult? TrySplit(byte[] input);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !EXCLUDE_HACKS
|
||||
/// <summary>
|
||||
/// Provides handling for recognizing atypical save file formats.
|
||||
/// </summary>
|
||||
public interface ISaveReader : ISaveHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a save file from the <see cref="data"/>
|
||||
/// </summary>
|
||||
/// <param name="data">Raw input data</param>
|
||||
/// <param name="path">Optional file path.</param>
|
||||
/// <returns>Save File object, or null if invalid. Check <see cref="ISaveHandler"/> if it is compatible first.</returns>
|
||||
SaveFile? ReadSaveFile(byte[] data, string? path = null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -61,6 +61,15 @@ public static class SaveUtil
|
||||
|
||||
private static readonly SaveHandlerGCI DolphinHandler = new();
|
||||
|
||||
#if !EXCLUDE_HACKS
|
||||
/// <summary>
|
||||
/// Specialized readers for loading save files from non-standard games (e.g. hacks).
|
||||
/// </summary>
|
||||
// ReSharper disable once CollectionNeverUpdated.Global
|
||||
public static readonly List<ISaveReader> CustomSaveReaders = new();
|
||||
#endif
|
||||
|
||||
#if !EXCLUDE_EMULATOR_FORMATS
|
||||
/// <summary>
|
||||
/// Pre-formatters for loading save files from non-standard formats (e.g. emulators).
|
||||
/// </summary>
|
||||
@@ -70,6 +79,7 @@ public static class SaveUtil
|
||||
new SaveHandlerDeSmuME(),
|
||||
new SaveHandlerARDS(),
|
||||
};
|
||||
#endif
|
||||
|
||||
internal static readonly HashSet<int> SizesSWSH = new()
|
||||
{
|
||||
@@ -487,7 +497,7 @@ private static GameVersion GetIsG8SAV(byte[] data)
|
||||
public static SaveFile? GetVariantSAV(string path)
|
||||
{
|
||||
var data = File.ReadAllBytes(path);
|
||||
var sav = GetVariantSAV(data);
|
||||
var sav = GetVariantSAV(data, path);
|
||||
if (sav == null)
|
||||
return null;
|
||||
sav.Metadata.SetExtraInfo(path);
|
||||
@@ -496,13 +506,27 @@ private static GameVersion GetIsG8SAV(byte[] data)
|
||||
|
||||
/// <summary>Creates an instance of a SaveFile using the given save data.</summary>
|
||||
/// <param name="data">Save data from which to create a SaveFile.</param>
|
||||
/// <param name="path">Optional save file path, may help initialize a non-standard save file format.</param>
|
||||
/// <returns>An appropriate type of save file for the given data, or null if the save data is invalid.</returns>
|
||||
public static SaveFile? GetVariantSAV(byte[] data)
|
||||
public static SaveFile? GetVariantSAV(byte[] data, string? path = null)
|
||||
{
|
||||
#if !EXCLUDE_HACKS
|
||||
foreach (var h in CustomSaveReaders)
|
||||
{
|
||||
if (!h.IsRecognized(data.Length))
|
||||
continue;
|
||||
|
||||
var custom = h.ReadSaveFile(data, path);
|
||||
if (custom != null)
|
||||
return custom;
|
||||
}
|
||||
#endif
|
||||
|
||||
var sav = GetVariantSAVInternal(data);
|
||||
if (sav != null)
|
||||
return sav;
|
||||
|
||||
#if !EXCLUDE_EMULATOR_FORMATS
|
||||
foreach (var h in Handlers)
|
||||
{
|
||||
if (!h.IsRecognized(data.Length))
|
||||
@@ -519,6 +543,7 @@ private static GameVersion GetIsG8SAV(byte[] data)
|
||||
sav.Metadata.SetExtraInfo(split.Header, split.Footer);
|
||||
return sav;
|
||||
}
|
||||
#endif
|
||||
|
||||
// unrecognized.
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user