diff --git a/PKHeX.Core/PKM/Editing/CommonEdits.cs b/PKHeX.Core/Editing/CommonEdits.cs
similarity index 100%
rename from PKHeX.Core/PKM/Editing/CommonEdits.cs
rename to PKHeX.Core/Editing/CommonEdits.cs
diff --git a/PKHeX.Core/PKM/Editing/HiddenPower.cs b/PKHeX.Core/Editing/HiddenPower.cs
similarity index 100%
rename from PKHeX.Core/PKM/Editing/HiddenPower.cs
rename to PKHeX.Core/Editing/HiddenPower.cs
diff --git a/PKHeX.Core/Editing/IPKMView.cs b/PKHeX.Core/Editing/IPKMView.cs
new file mode 100644
index 000000000..44ed4d0a7
--- /dev/null
+++ b/PKHeX.Core/Editing/IPKMView.cs
@@ -0,0 +1,48 @@
+namespace PKHeX.Core
+{
+ ///
+ /// Simple interface representing a viewer.
+ ///
+ public interface IPKMView
+ {
+ ///
+ /// Fetches the currently loaded data from the viewer.
+ ///
+ PKM Data { get; }
+
+ ///
+ /// Indicates if the Viewer supports using Unicode characters or not.
+ ///
+ bool Unicode { get; }
+
+ ///
+ /// Indicates if the Viewer's controls have been fully initialized after a reload.
+ ///
+ bool FieldsInitialized { get; }
+
+ ///
+ /// Indicates if the Viewer is providing extra flexibility or not.
+ ///
+ bool HaX { get; }
+
+ ///
+ /// Indicates if the Viewer's controls are changing their values and should avoid triggering other updates.
+ ///
+ bool ChangingFields { get; set; }
+
+ ///
+ /// Fetches the currently loaded data from the viewer by finishing any pending changes or auto-modifications.
+ ///
+ /// Cause the viewer to do extra actions to force validation of its children.
+ /// Prepared data from the viewer.
+ PKM PreparePKM(bool click = true);
+
+ ///
+ /// Loads a given data to the viewer.
+ ///
+ /// Pokémon data to load.
+ /// Cause the viewer to give focus to itself.
+ /// Cause the viewer to skip converting the data. Faster if it is known that the format is the same as the previous format.
+ void PopulateFields(PKM pk, bool focus = true, bool skipConversionCheck = false);
+ }
+}
diff --git a/PKHeX.Core/Editing/IPlugin.cs b/PKHeX.Core/Editing/IPlugin.cs
new file mode 100644
index 000000000..c3349d7f9
--- /dev/null
+++ b/PKHeX.Core/Editing/IPlugin.cs
@@ -0,0 +1,10 @@
+namespace PKHeX.Core
+{
+ public interface IPlugin
+ {
+ string Name { get; }
+ void Initialize(params object[] args);
+ void NotifySaveLoaded();
+ ISaveFileProvider SaveFileEditor { get; }
+ }
+}
diff --git a/PKHeX.Core/Editing/ISaveFileProvider.cs b/PKHeX.Core/Editing/ISaveFileProvider.cs
new file mode 100644
index 000000000..83c527817
--- /dev/null
+++ b/PKHeX.Core/Editing/ISaveFileProvider.cs
@@ -0,0 +1,23 @@
+namespace PKHeX.Core
+{
+ ///
+ /// Simple interface representing a Save File viewer.
+ ///
+ public interface ISaveFileProvider
+ {
+ ///
+ /// Retrieves the save file the has control over.
+ ///
+ SaveFile SAV { get; }
+
+ ///
+ /// Retrieves the current box the has control over.
+ ///
+ int CurrentBox { get; }
+
+ ///
+ /// Triggers a refresh of any individual view slots.
+ ///
+ void ReloadSlots();
+ }
+}
diff --git a/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs
index 716d1b8e9..265ad855d 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs
@@ -2,15 +2,9 @@
namespace PKHeX.WinForms.Controls
{
- public interface IMainEditor
+ public interface IMainEditor : IPKMView
{
- bool Unicode { get; }
- bool FieldsInitialized { get; }
- bool ChangingFields { get; set; }
- bool HaX { get; }
-
- PKM pkm { get; }
-
void UpdateIVsGB(bool skipForm);
+ PKM pkm { get; }
}
}
\ No newline at end of file
diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
index fa2c1280d..87751c3ae 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
@@ -62,6 +62,7 @@ private void SavePartyStats(PKM pk)
public bool HaX { get; set; }
public byte[] LastData { private get; set; }
+ public PKM Data { get => pkm; set => pkm = value; }
public PKM pkm { get; private set; }
public bool FieldsInitialized { get; private set; }
public bool FieldsLoaded { get; private set; }
diff --git a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs
index 96a25f996..ed690997e 100644
--- a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs
+++ b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs
@@ -13,9 +13,10 @@
namespace PKHeX.WinForms.Controls
{
- public partial class SAVEditor : UserControl, ISlotViewer
+ public partial class SAVEditor : UserControl, ISlotViewer, ISaveFileProvider
{
- public SaveFile SAV;
+ public SaveFile SAV { get; set; }
+ public int CurrentBox => Box.CurrentBox;
public SlotChangeManager M { get; }
public readonly Stack UndoStack = new Stack();
public readonly Stack RedoStack = new Stack();
diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs
index df719d9c3..8ad4817cf 100644
--- a/PKHeX.WinForms/MainWindow/Main.cs
+++ b/PKHeX.WinForms/MainWindow/Main.cs
@@ -83,6 +83,7 @@ private set
"中文", // CHN
"Português", // Portuguese
};
+ private static readonly List Plugins = new List();
#endregion
#region Path Variables
@@ -92,6 +93,7 @@ private set
public static string MGDatabasePath => Path.Combine(WorkingDirectory, "mgdb");
public static string BackupPath => Path.Combine(WorkingDirectory, "bak");
private static string TemplatePath => Path.Combine(WorkingDirectory, "template");
+ private static string PluginPath => Path.Combine(WorkingDirectory, "plugins");
private const string ThreadPath = "https://projectpokemon.org/pkhex/";
private const string VersionPath = "https://raw.githubusercontent.com/kwsch/PKHeX/master/PKHeX.WinForms/Resources/text/version.txt";
@@ -125,6 +127,8 @@ private void FormLoadInitialSettings(string[] args, out bool showChangelog, out
WinFormsUtil.Error(MsgSettingsLoadFail, e);
}
+ FormLoadPlugins();
+
PKME_Tabs.InitializeFields();
PKME_Tabs.TemplateFields(LoadTemplate(C_SAV.SAV));
}
@@ -246,6 +250,14 @@ private void FormLoadConfig(out bool BAKprompt, out bool showChangelog)
Settings.Version = Resources.ProgramVersion;
}
+ private void FormLoadPlugins()
+ {
+ if (!Directory.Exists(PluginPath))
+ return;
+ Plugins.AddRange(PluginLoader.LoadPlugins(PluginPath));
+ foreach (var p in Plugins)
+ p.Initialize(C_SAV, PKME_Tabs, menuStrip1);
+ }
private static void DeleteConfig(string settingsFilename)
{
var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgSettingsResetCorrupt, MsgSettingsResetPrompt);
@@ -746,6 +758,8 @@ private void ResetSAVPKMEditors(SaveFile sav)
PKME_Tabs.FlickerInterface();
PKME_Tabs.TemplateFields(LoadTemplate(sav));
+ foreach (var p in Plugins)
+ p.NotifySaveLoaded();
sav.Edited = false;
}
private static string GetProgramTitle()
diff --git a/PKHeX.WinForms/MainWindow/PluginLoader.cs b/PKHeX.WinForms/MainWindow/PluginLoader.cs
new file mode 100644
index 000000000..409faad1a
--- /dev/null
+++ b/PKHeX.WinForms/MainWindow/PluginLoader.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace PKHeX.WinForms
+{
+ public static class PluginLoader
+ {
+ public static IEnumerable LoadPlugins(string pluginPath)
+ {
+ var dllFileNames = Directory.EnumerateFiles(pluginPath, "*.dll", SearchOption.AllDirectories);
+ var assemblies = GetAssemblies(dllFileNames);
+ var pluginTypes = GetPluginsOfType(assemblies);
+ return LoadPlugins(pluginTypes);
+ }
+ private static IEnumerable LoadPlugins(IEnumerable pluginTypes)
+ {
+ return pluginTypes.Select(type => (T)Activator.CreateInstance(type));
+ }
+ private static IEnumerable GetAssemblies(IEnumerable dllFileNames)
+ {
+ return dllFileNames.Select(AssemblyName.GetAssemblyName).Select(Assembly.Load);
+ }
+ private static IEnumerable GetPluginsOfType(IEnumerable assemblies)
+ {
+ var pluginType = typeof(T);
+ foreach (var type in assemblies.Where(z => z != null).SelectMany(a => a.GetTypes()))
+ {
+ if (type.IsInterface || type.IsAbstract)
+ continue;
+ if (type.GetInterface(pluginType.FullName) == null)
+ continue;
+ yield return type;
+ }
+ }
+ }
+}
diff --git a/PKHeX.WinForms/PKHeX.WinForms.csproj b/PKHeX.WinForms/PKHeX.WinForms.csproj
index 7742a7720..2b0db0bd4 100644
--- a/PKHeX.WinForms/PKHeX.WinForms.csproj
+++ b/PKHeX.WinForms/PKHeX.WinForms.csproj
@@ -245,6 +245,7 @@
PKMEditor.cs
+
Form