From ab4bcea61a3511885b31f938300a08a19b2050d0 Mon Sep 17 00:00:00 2001
From: NM <35472796+NM-20@users.noreply.github.com>
Date: Wed, 12 Oct 2022 17:58:01 -0400
Subject: [PATCH 1/3] [Editor, Core, & ModManager] Improved Loaded Plugins List
UI and improved PluginManager
---
FrostyEditor/BuildDate.txt | 2 +-
FrostyEditor/Windows/MainWindow.xaml | 69 +-
FrostyEditor/Windows/MainWindow.xaml.cs | 14 +-
FrostyModManager/BuildDate.txt | 2 +-
FrostyModManager/Windows/MainWindow.xaml | 1469 ++++++++++++++-----
FrostyModManager/Windows/MainWindow.xaml.cs | 14 +-
FrostyPlugin/FrostyCore.csproj | 10 +
FrostyPlugin/Images/Cross_White.png | Bin 0 -> 419 bytes
FrostyPlugin/Images/Invalid_White.png | Bin 0 -> 270 bytes
FrostyPlugin/Images/Tick_White.png | Bin 0 -> 430 bytes
FrostyPlugin/Plugin.cs | 108 ++
FrostyPlugin/PluginLoadStatus.cs | 26 +
FrostyPlugin/PluginLoadType.cs | 23 +
FrostyPlugin/PluginManager.cs | 442 +++---
FrostyPlugin/PluginManagerType.cs | 29 +
FrostyPlugin/ShaderDefinition.cs | 47 +
Plugins/BlankPlugin/BuildDate.txt | 2 +-
Plugins/LaunchPlatformPlugin/BuildDate.txt | 2 +-
18 files changed, 1637 insertions(+), 622 deletions(-)
create mode 100644 FrostyPlugin/Images/Cross_White.png
create mode 100644 FrostyPlugin/Images/Invalid_White.png
create mode 100644 FrostyPlugin/Images/Tick_White.png
create mode 100644 FrostyPlugin/Plugin.cs
create mode 100644 FrostyPlugin/PluginLoadStatus.cs
create mode 100644 FrostyPlugin/PluginLoadType.cs
create mode 100644 FrostyPlugin/PluginManagerType.cs
create mode 100644 FrostyPlugin/ShaderDefinition.cs
diff --git a/FrostyEditor/BuildDate.txt b/FrostyEditor/BuildDate.txt
index b5326c725..e79ce8caf 100644
--- a/FrostyEditor/BuildDate.txt
+++ b/FrostyEditor/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 15:03:43.07
\ No newline at end of file
+Wed 10/12/2022 17:36:47.21
diff --git a/FrostyEditor/Windows/MainWindow.xaml b/FrostyEditor/Windows/MainWindow.xaml
index 2ba7b578c..bdc828c55 100644
--- a/FrostyEditor/Windows/MainWindow.xaml
+++ b/FrostyEditor/Windows/MainWindow.xaml
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:FrostyEditor"
xmlns:ctrl2="clr-namespace:Frosty.Controls;assembly=FrostyControls"
xmlns:core="clr-namespace:Frosty.Core.Controls;assembly=FrostyCore"
+ xmlns:coreroot="clr-namespace:Frosty.Core;assembly=FrostyCore"
xmlns:conv="clr-namespace:Frosty.Core.Converters;assembly=FrostyCore"
xmlns:cmd="clr-namespace:FrostyEditor.Commands"
xmlns:ext="clr-namespace:FrostyEditor.Extensions"
@@ -33,6 +34,15 @@
+
+
+
@@ -661,7 +671,11 @@
-
+
@@ -702,10 +716,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FrostyEditor/Windows/MainWindow.xaml.cs b/FrostyEditor/Windows/MainWindow.xaml.cs
index 95c97fc3a..49b9bee89 100644
--- a/FrostyEditor/Windows/MainWindow.xaml.cs
+++ b/FrostyEditor/Windows/MainWindow.xaml.cs
@@ -125,7 +125,7 @@ public MainWindow()
LoadTabExtensions();
LoadDataExplorerMenuItemExtensions();
- LoadedPluginsList.ItemsSource = App.PluginManager.LoadedPlugins;
+ LoadedPluginsList.ItemsSource = App.PluginManager.Plugins;
if (toolsMenuItem.Items.Count != 0)
toolsMenuItem.Items.Add(new Separator());
@@ -1522,5 +1522,17 @@ public void RefreshRecentProjects()
recentProjectsMenuItem.Items.Add(m_clearRecentsMenuItem);
recentProjectsMenuItem.IsEnabled = true;
}
+
+ private void CopyFullExceptionMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ Plugin selectedPlugin = (Plugin)LoadedPluginsList.SelectedItem;
+
+ // retrieve the selected plugin's load exception, execute ToString on it, and add the result to the clipboard
+ Clipboard.SetText(string.Format("[{0}]\n{1}", new string[]
+ {
+ DateTime.Now.ToString(),
+ selectedPlugin.LoadException.ToString()
+ }));
+ }
}
}
diff --git a/FrostyModManager/BuildDate.txt b/FrostyModManager/BuildDate.txt
index b5326c725..e79ce8caf 100644
--- a/FrostyModManager/BuildDate.txt
+++ b/FrostyModManager/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 15:03:43.07
\ No newline at end of file
+Wed 10/12/2022 17:36:47.21
diff --git a/FrostyModManager/Windows/MainWindow.xaml b/FrostyModManager/Windows/MainWindow.xaml
index 7a053d9e7..214699021 100644
--- a/FrostyModManager/Windows/MainWindow.xaml
+++ b/FrostyModManager/Windows/MainWindow.xaml
@@ -1,50 +1,86 @@
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:FrostyModManager"
+ xmlns:ctrl="clr-namespace:Frosty.Controls;assembly=FrostyControls"
+ xmlns:localctrl="clr-namespace:FrostyModManager.Controls"
+ xmlns:conv="clr-namespace:Frosty.Core.Converters;assembly=FrostyCore"
+ xmlns:coreroot="clr-namespace:Frosty.Core;assembly=FrostyCore"
+ mc:Ignorable="d"
+ Title="Frosty Mod Manager"
+ Height="750"
+ Width="1050"
+ Icon="/FrostyModManager;component/AppIcon.ico"
+ FrostyLoaded="FrostyWindow_FrostyLoaded"
+ Closing="FrostyWindow_Closing"
+ AllowDrop="True"
+ Drop="FrostyWindow_Drop">
-
-
-
-
-
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
-
-
+
+
+
-
-
+
+
-
+
@@ -222,84 +395,133 @@
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
@@ -491,31 +856,51 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
@@ -523,24 +908,37 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
@@ -549,141 +947,266 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
@@ -824,59 +1462,102 @@
-
+
-
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -884,26 +1565,40 @@
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
diff --git a/FrostyModManager/Windows/MainWindow.xaml.cs b/FrostyModManager/Windows/MainWindow.xaml.cs
index c768ab5a0..e22cde6f1 100644
--- a/FrostyModManager/Windows/MainWindow.xaml.cs
+++ b/FrostyModManager/Windows/MainWindow.xaml.cs
@@ -477,7 +477,7 @@ private void FrostyWindow_FrostyLoaded(object sender, EventArgs e)
{
}
- LoadedPluginsList.ItemsSource = App.PluginManager.LoadedPlugins;
+ LoadedPluginsList.ItemsSource = App.PluginManager.Plugins;
if (Config.Get("ApplyModOrder", "List") == "List")
{
@@ -1915,5 +1915,17 @@ private void orderComboBox_SelectionChanged(object sender, SelectionChangedEvent
updateAppliedModButtons();
}
+
+ private void CopyFullExceptionMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ Plugin selectedPlugin = (Plugin)LoadedPluginsList.SelectedItem;
+
+ // retrieve the selected plugin's load exception, execute ToString on it, and add the result to the clipboard
+ Clipboard.SetText(string.Format("[{0}]\n{1}", new string[]
+ {
+ DateTime.Now.ToString(),
+ selectedPlugin.LoadException.ToString()
+ }));
+ }
}
}
\ No newline at end of file
diff --git a/FrostyPlugin/FrostyCore.csproj b/FrostyPlugin/FrostyCore.csproj
index 26a912180..037024d96 100644
--- a/FrostyPlugin/FrostyCore.csproj
+++ b/FrostyPlugin/FrostyCore.csproj
@@ -172,6 +172,11 @@
+
+
+
+
+
@@ -416,5 +421,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/FrostyPlugin/Images/Cross_White.png b/FrostyPlugin/Images/Cross_White.png
new file mode 100644
index 0000000000000000000000000000000000000000..1d3a3480364b6fc01bf887aa02db17bca535e928
GIT binary patch
literal 419
zcmV;U0bKrxP)p-dDg75v}BX
z1y~VPLh{O&e29P)5y9j>0kNyNiNlF}k}EJ(oCp_h?#>_Dg4E;|TZtVcz!2XyabnS^>T%wTTtUk=QEYySGodMnJAu)xSPQwQ!_8OsM=J9(7%+>8zJJLnWx@E4cW)izom(swS1RU~
zD=?}w)G;nG^kKMokLi7T3RjBg@07G~|G526t(X`*B?V4By?Ewa;e=Vaaw?*~R!k77
z3qQtu;_KQwlb^~SF6=eW6i$eL{MN?tUUdS;n#Ri0LGy5AA`Hat!uyJS)%ULnfylfSB&BcpzNb2O81>sIE3(H_-eI7!18TLIL7H
z%*MIA;sA(gx1?bNMK+K=cX#}7g*ZeO4wGmwf&Vacj=3an8|4$pF07*qoM6N<$f(5O>o&W#<
literal 0
HcmV?d00001
diff --git a/FrostyPlugin/Plugin.cs b/FrostyPlugin/Plugin.cs
new file mode 100644
index 000000000..27cdbf45a
--- /dev/null
+++ b/FrostyPlugin/Plugin.cs
@@ -0,0 +1,108 @@
+using Frosty.Core.Attributes;
+using System;
+using System.IO;
+using System.Reflection;
+
+namespace Frosty.Core
+{
+ public class Plugin
+ {
+ // Entirely refactored this class to simply make it better overall
+
+ ///
+ /// The author of this .
+ ///
+ public string Author
+ {
+ get
+ {
+ // Create a string for storing the retrieved author of this plugin's associated assembly
+ string author = Assembly?.GetCustomAttribute()?.Author;
+
+ // If the author is not null or empty, return it; otherwise, return unknown
+ return !string.IsNullOrEmpty(author) ? author : "Unknown";
+ }
+ }
+
+ ///
+ /// The assembly associated with this .
+ ///
+ public Assembly Assembly
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// An exception that may have occurred as a result of loading this .
+ ///
+ public Exception LoadException
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The display name of this .
+ ///
+ public string Name
+ {
+ get
+ {
+ // Create a string for storing the retrieved display name of this plugin
+ string name = Assembly?.GetCustomAttribute()?.DisplayName;
+
+ // Return the display name or the file name without its extension
+ return !string.IsNullOrEmpty(name) ? name : Path.GetFileNameWithoutExtension(SourcePath);
+ }
+ }
+
+ ///
+ /// The path at which this was located.
+ ///
+ public string SourcePath
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// The load status of this .
+ ///
+ public PluginLoadStatus Status
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The version of this .
+ ///
+ public string Version
+ {
+ get
+ {
+ // Create a string for storing the version of this plugin
+ string version = Assembly?.GetCustomAttribute()?.Version;
+
+ // Return the version if it is not null or empty; otherwise, return a default version of 1.0.0.0
+ return !string.IsNullOrEmpty(version) ? version : "1.0.0.0";
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The assembly to be used.
+ /// The that hosts this plugin. This is essential for the ability to
+ /// The path to the plugin's assembly.
+ public Plugin(Assembly assembly, string sourcePath)
+ {
+ // Assign to the assembly
+ Assembly = assembly;
+
+ // Assign to the source path
+ SourcePath = sourcePath;
+ }
+ }
+}
diff --git a/FrostyPlugin/PluginLoadStatus.cs b/FrostyPlugin/PluginLoadStatus.cs
new file mode 100644
index 000000000..0254959cb
--- /dev/null
+++ b/FrostyPlugin/PluginLoadStatus.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Frosty.Core
+{
+ public enum PluginLoadStatus
+ {
+ ///
+ /// An enum entry that indicates that the associated plugin has failed to load.
+ ///
+ Failed,
+
+ ///
+ /// An enum entry that indicates that the associated plugin has successfully loaded.
+ ///
+ Loaded,
+
+ ///
+ /// An enum entry that indicates that the associated plugin has successfully loaded, but is invalid for the currently loaded profile.
+ ///
+ LoadedInvalid
+ }
+}
diff --git a/FrostyPlugin/PluginLoadType.cs b/FrostyPlugin/PluginLoadType.cs
new file mode 100644
index 000000000..194d4ff2a
--- /dev/null
+++ b/FrostyPlugin/PluginLoadType.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Frosty.Core
+{
+ ///
+ /// Describes when the plugin should be loaded.
+ ///
+ public enum PluginLoadType
+ {
+ ///
+ /// The plugin loads on app startup.
+ ///
+ Startup,
+ ///
+ /// The plugin loads during the profile loading process.
+ ///
+ Initialize
+ }
+}
diff --git a/FrostyPlugin/PluginManager.cs b/FrostyPlugin/PluginManager.cs
index 4ee26846d..c39c41736 100644
--- a/FrostyPlugin/PluginManager.cs
+++ b/FrostyPlugin/PluginManager.cs
@@ -13,174 +13,106 @@
namespace Frosty.Core
{
///
- /// Describes when the plugin should be loaded.
+ /// Represents the core plugin manager responsible for loading and managing of plugin extensions.
///
- public enum PluginLoadType
+ public sealed class PluginManager
{
- ///
- /// The plugin loads on app startup.
- ///
- Startup,
- ///
- /// The plugin loads during the profile loading process.
- ///
- Initialize
- }
+ private List m_contextMenuItemExtensions = new List();
- ///
- /// Describes the context in which the plugin manager is loading.
- ///
- public enum PluginManagerType
- {
- ///
- /// The plugin is loading into the editor.
- ///
- Editor,
+ private Dictionary m_customHandlers = new Dictionary();
- ///
- /// The plugin is loading into the mod manager.
- ///
- ModManager,
+ private Dictionary m_definitions = new Dictionary();
- ///
- /// The plugin is loading for both the editor and mod manager.
- ///
- Both
- }
+ private List m_executionActions = new List();
- ///
- /// Represents a shader loaded from a plugin
- ///
- public sealed class ShaderDefinition
- {
- ///
- /// Gets the plugin in which the shader is located.
- ///
- /// The that represents the plugin.
- public Assembly Assembly { get; private set; }
+ private Dictionary m_globalTypeEditors = new Dictionary();
- ///
- /// Gets the name of the shader resource file in the format of Namespace.ResourceName.
- ///
- /// The name of the shader resource file.
- public string ResourceName { get; set; }
+ private List m_loadedPlugins = new List();
- ///
- /// Gets the type of shader.
- ///
- /// The type of shader.
- public ShaderType ShaderType { get; set; }
+ private Type m_localizedStringDatabaseType;
- ///
- /// Initializes a new instance of the class with the plugin, shader type, and resource name.
- ///
- /// The plugin in which the shader is located.
- /// The type of shader.
- /// The resource name of the shader in the format of Namespace.ResourceName.
- public ShaderDefinition(Assembly plugin, ShaderType type, string resourceName)
- {
- Assembly = plugin;
- ShaderType = type;
- ResourceName = resourceName;
- }
- }
+ private PluginManagerType m_managerType;
- public class Plugin
- {
- public string Name { get; private set; }
- public string Author { get; private set; }
- public string Version { get; private set; }
+ private List m_menuExtensions = new List();
- public Assembly Assembly { get; private set; }
+ private List m_optionsExtensions = new List();
- public Plugin(string name, string author, string version, Assembly assembly)
- {
- Name = name;
- Author = author;
- Version = version;
+ private List m_plugins = new List();
- Assembly = assembly;
- }
- }
+ private List m_profiles = new List();
+
+ private Dictionary m_resCustomHandlers = new Dictionary();
+
+ private Dictionary m_shaders = new Dictionary();
+
+ private List m_startupActions = new List();
+
+ private List m_tabExtensions = new List();
+
+ private List m_thirdPartyDlls = new List();
+
+ private Dictionary m_typeOverrides = new Dictionary();
+
+ private List m_userShaders = new List();
- ///
- /// Represents the core plugin manager responsible for loading and managing of plugin extensions.
- ///
- public sealed class PluginManager
- {
///
- /// Retreives a collection of menu extensions that have been loaded from plugins.
+ /// Retrieves a collection of data explorer context menu item extensions that have been loaded from plugins.
///
/// A collection of menu extensions.
- public IEnumerable MenuExtensions => menuExtensions;
+ public IEnumerable DataExplorerContextMenuExtensions => m_contextMenuItemExtensions;
///
- /// Retreives a collection of menu extensions that have been loaded from plugins.
+ /// Retrieves a collection of execution actions that have been loaded from plugins.
///
- /// A collection of menu extensions.
- public IEnumerable TabExtensions => tabExtensions;
+ /// A collection of execution actions.
+ public IEnumerable ExecutionActions => m_executionActions;
///
- /// Retreives a collection of data explorer context menu item extensions that have been loaded from plugins.
+ /// Retrieves a collection of loaded plugins.
///
- /// A collection of menu extensions.
- public IEnumerable DataExplorerContextMenuExtensions => contextMenuItemExtensions;
+ /// A collection of loaded plugins.
+ public IEnumerable LoadedPlugins => m_loadedPlugins;
///
- /// Retrieves a collection of options extensions that have been loaded from plugins.
+ /// Retrieves an enum defining which manager is being loaded right now.
///
- /// A collection of options extensions.
- public IEnumerable OptionsExtensions => optionsExtensions;
+ /// An enum defining which manager is being loaded right now..
+ public PluginManagerType ManagerType => m_managerType;
///
- /// Retreives a collection of profiles that have been loaded from plugins.
+ /// Retrieves a collection of menu extensions that have been loaded from plugins.
///
- /// A collection of profiles.
- public IEnumerable Profiles => profiles;
+ /// A collection of menu extensions.
+ public IEnumerable MenuExtensions => m_menuExtensions;
///
- /// Retreives a collection of startup actions that have been loaded from plugins.
+ /// Retrieves a collection of options extensions that have been loaded from plugins.
///
- /// A collection of startup actions.
- public IEnumerable StartupActions => startupActions;
+ /// A collection of options extensions.
+ public IEnumerable OptionsExtensions => m_optionsExtensions;
///
- /// Retreives a collection of execution actions that have been loaded from plugins.
+ /// An of all plugins that have been found.
///
- /// A collection of execution actions.
- public IEnumerable ExecutionActions => executionActions;
+ public IEnumerable Plugins => m_plugins;
///
- /// Retreives a collection of loaded plugins.
+ /// Retrieves a collection of profiles that have been loaded from plugins.
///
- /// A collection of loaded plugins.
- public IEnumerable LoadedPlugins => loadedPlugins;
+ /// A collection of profiles.
+ public IEnumerable Profiles => m_profiles;
///
- /// Retreives an enum defining which manager is being loaded right now.
+ /// Retrieves a collection of menu extensions that have been loaded from plugins.
///
- /// An enum defining which manager is being loaded right now..
- public PluginManagerType ManagerType => managerType;
-
- private Dictionary definitions = new Dictionary();
- private List menuExtensions = new List();
- private List tabExtensions = new List();
- private List contextMenuItemExtensions = new List();
- private Dictionary globalTypEditors = new Dictionary();
- private Dictionary typeOverrides = new Dictionary();
- private List optionsExtensions = new List();
- private List thirdPartyDlls = new List();
- private List profiles = new List();
- private List plugins = new List();
- private List loadedPlugins = new List();
- private List executionActions = new List();
- private List startupActions = new List();
- private Dictionary customHandlers = new Dictionary();
- private Dictionary resCustomHandlers = new Dictionary();
- private Dictionary shaders = new Dictionary();
- private List userShaders = new List();
- private Type localizedStringDatabaseType;
- private PluginManagerType managerType;
+ /// A collection of menu extensions.
+ public IEnumerable TabExtensions => m_tabExtensions;
+
+ ///
+ /// Retrieves a collection of startup actions that have been loaded from plugins.
+ ///
+ /// A collection of startup actions.
+ public IEnumerable StartupActions => m_startupActions;
///
/// Initializes a new instance of the class with the specified logger and context.
@@ -189,57 +121,28 @@ public sealed class PluginManager
/// The context which this plugin should load for.
public PluginManager(ILogger logger, PluginManagerType context)
{
- managerType = context;
+ m_managerType = context;
+
+ // Check if the plugins directory doesn't exist
+ if (!Directory.Exists("Plugins"))
+ {
+ // Inform the user of the missing directory
+ logger.Log("The \"Plugins\" directory could not be located within the executable's associated directory. Due to some plugins being a necessity for functionality, please retrieve a copy of the needed directory from a clean archive of the editor/mod manager.");
- logger.Log("");
- logger.Log($"Scanning '{new FileInfo(Assembly.GetEntryAssembly().Location).DirectoryName}\\Plugins' for plugins");
+ // Prevent further execution
+ return;
+ }
- // load from main executable
LoadDefinitionsFromAssembly(PluginLoadType.Startup, Assembly.GetEntryAssembly());
LoadDefinitionsFromAssembly(PluginLoadType.Startup, Assembly.GetExecutingAssembly());
- int pluginCount = 0;
- // now load from plugins directory
- if (Directory.Exists("Plugins"))
+ foreach (string item in Directory.EnumerateFiles("Plugins", "*.dll", SearchOption.AllDirectories))
{
- foreach (string pluginPath in Directory.EnumerateFiles("Plugins", "*.dll", SearchOption.AllDirectories))
- {
- FileInfo fi = new FileInfo(pluginPath);
- string statusText = "Located plugin ";
-
- try
- {
- var assembly = Assembly.LoadFile(fi.FullName);
-
- LoadDefinitionsFromAssembly(PluginLoadType.Startup, assembly);
-
- var displayName = assembly.GetCustomAttribute()?.DisplayName;
- var author = assembly.GetCustomAttribute()?.Author;
- var version = assembly.GetCustomAttribute()?.Version;
-
- if (string.IsNullOrEmpty(displayName))
- displayName = fi.Name;
- if (string.IsNullOrEmpty(author))
- author = "Unknown";
- if (string.IsNullOrEmpty(version))
- version = "1.0.0.0";
-
- statusText += displayName + " (v" + version + ") by " + author;
- pluginCount++;
+ FileInfo fileInfo = new FileInfo(item);
- plugins.Add(new Plugin(displayName, author, version, assembly));
- logger.Log(statusText);
- }
- catch (Exception e)
- {
- statusText += fi.Name + " - Failed (" + e.Message + ")";
- logger.Log(statusText);
- }
- }
+ // Add the plugin to the list of located plugins
+ m_plugins.Add(LoadPlugin(fileInfo.FullName, PluginLoadType.Startup));
}
-
- logger.Log("Found a total of {0} plugins", pluginCount);
- logger.Log("");
}
///
@@ -247,13 +150,20 @@ public PluginManager(ILogger logger, PluginManagerType context)
///
public void Initialize()
{
- foreach (Plugin plugin in plugins)
+ foreach (Plugin plugin in m_plugins)
{
- if (!IsValidToLoadPlugin(plugin.Assembly))
+ if (IsValidToLoadPlugin(plugin.Assembly))
+ {
+ LoadDefinitionsFromAssembly(PluginLoadType.Initialize, plugin.Assembly);
+
+ // since IsValidToLoadPlugin does not block out Startup plugins, we can simply use this method as a means of adding to the loadedPlugins list
+ // this also filters out plugins invalid for the current profile
+ m_loadedPlugins.Add(plugin);
continue;
+ }
- LoadDefinitionsFromAssembly(PluginLoadType.Initialize, plugin.Assembly);
- loadedPlugins.Add(plugin);
+ // assign to the current plugin's status with an invalid load status if it did not pass the validity checks
+ plugin.Status = PluginLoadStatus.LoadedInvalid;
}
}
@@ -268,7 +178,7 @@ public AssetDefinition GetAssetDefinition(string type)
return null;
type = type.ToLower();
- return !definitions.ContainsKey(type) ? null : definitions[type];
+ return !m_definitions.ContainsKey(type) ? null : m_definitions[type];
}
///
@@ -279,9 +189,9 @@ public AssetDefinition GetAssetDefinition(string type)
public Type GetTypeEditor(string lookupName)
{
lookupName = lookupName.ToLower();
- if (!globalTypEditors.ContainsKey(lookupName))
+ if (!m_globalTypeEditors.ContainsKey(lookupName))
return null;
- return globalTypEditors[lookupName];
+ return m_globalTypeEditors[lookupName];
}
///
@@ -292,9 +202,9 @@ public Type GetTypeEditor(string lookupName)
public Type GetTypeOverride(string lookupName)
{
lookupName = lookupName.ToLower();
- if (!typeOverrides.ContainsKey(lookupName))
+ if (!m_typeOverrides.ContainsKey(lookupName))
return null;
- return typeOverrides[lookupName];
+ return m_typeOverrides[lookupName];
}
///
@@ -305,14 +215,14 @@ public Type GetTypeOverride(string lookupName)
public bool IsThirdPartyDll(string name)
{
name = name.ToLower();
- return thirdPartyDlls.Contains(name);
+ return m_thirdPartyDlls.Contains(name);
}
///
/// Returns true if the loaded manager is the same a the specific manager type.
///
/// A boolean if the loaded manager is the specified manager type.
- public bool IsManagerType(PluginManagerType type) => type == managerType;
+ public bool IsManagerType(PluginManagerType type) => type == m_managerType;
///
/// Returns the of the specified plugin if it is loaded. Returns null otherwise.
@@ -321,7 +231,7 @@ public bool IsThirdPartyDll(string name)
/// The of the plugin.
public Assembly GetPluginAssembly(string name)
{
- foreach (var plugin in plugins)
+ foreach (var plugin in m_plugins)
{
if (plugin.Assembly.GetName().Name.Equals(name, StringComparison.OrdinalIgnoreCase))
return plugin.Assembly;
@@ -337,10 +247,10 @@ public Assembly GetPluginAssembly(string name)
public ILocalizedStringDatabase GetLocalizedStringDatabase()
{
ILocalizedStringDatabase localizedStringDb;
- if (localizedStringDatabaseType == null)
+ if (m_localizedStringDatabaseType == null)
localizedStringDb = new DefaultLocalizedStringDatabase();
else
- localizedStringDb = (ILocalizedStringDatabase)Activator.CreateInstance(localizedStringDatabaseType);
+ localizedStringDb = (ILocalizedStringDatabase)Activator.CreateInstance(m_localizedStringDatabaseType);
LocalizedStringDatabase.Current = localizedStringDb;
return localizedStringDb;
@@ -354,16 +264,16 @@ public ICustomActionHandler GetCustomHandler(string ebxType)
public ICustomActionHandler GetCustomHandler(uint handlerHash)
{
- if (!customHandlers.ContainsKey(handlerHash))
+ if (!m_customHandlers.ContainsKey(handlerHash))
return null;
- return (ICustomActionHandler)Activator.CreateInstance(customHandlers[handlerHash]);
+ return (ICustomActionHandler)Activator.CreateInstance(m_customHandlers[handlerHash]);
}
public ICustomActionHandler GetCustomHandler(ResourceType resType)
{
- if (!resCustomHandlers.ContainsKey(resType))
+ if (!m_resCustomHandlers.ContainsKey(resType))
return null;
- return (ICustomActionHandler)Activator.CreateInstance(resCustomHandlers[resType]);
+ return (ICustomActionHandler)Activator.CreateInstance(m_resCustomHandlers[resType]);
}
///
@@ -374,15 +284,15 @@ public ICustomActionHandler GetCustomHandler(ResourceType resType)
/// The bytecode of the shader.
public byte[] GetShader(ShaderType type, string name)
{
- if (!shaders.ContainsKey(name))
+ if (!m_shaders.ContainsKey(name))
return null;
ShaderDefinition shaderDef = null;
switch (type)
{
- case ShaderType.VertexShader: shaderDef = shaders[name][0]; break;
- case ShaderType.ComputeShader: shaderDef = shaders[name][0]; break;
- case ShaderType.PixelShader: shaderDef = shaders[name][1]; break;
+ case ShaderType.VertexShader: shaderDef = m_shaders[name][0]; break;
+ case ShaderType.ComputeShader: shaderDef = m_shaders[name][0]; break;
+ case ShaderType.PixelShader: shaderDef = m_shaders[name][1]; break;
}
if (shaderDef == null)
@@ -393,12 +303,77 @@ public byte[] GetShader(ShaderType type, string name)
public IEnumerable GetUserShaders()
{
- return userShaders;
+ return m_userShaders;
}
- // returns true if the specified plugin should be loaded (Based on ValidFor and NotValidFor attributes)
+ ///
+ /// Attempts to load a plugin located at the specified .
+ ///
+ /// The path to the target plugin.
+ /// Optional. The that determines what should be loaded from the plugin.
+ /// A instance regardless of whether or not a failure to load the plugin occurred. You may check for the potential of such failures through the property.
+ public Plugin LoadPlugin(string pluginPath, PluginLoadType? loadType = null)
+ {
+ Plugin loadedPlugin = new Plugin(null, pluginPath);
+
+ // create a variable of type Assembly for temporarily storing the loaded assembly until LoadDefinitionsFromAssembly finishes executing, allowing us to tell whether or not the assembly is a valid plugin before storing it with a Plugin instance
+ Assembly pluginAssembly;
+
+ // utilize a try catch statement to collect plugin load errors
+ try
+ {
+ pluginAssembly = Assembly.LoadFile(loadedPlugin.SourcePath);
+
+ switch (loadType)
+ {
+ case null:
+ // attempt to load everything from the plugin
+ LoadDefinitionsFromAssembly(PluginLoadType.Startup, pluginAssembly);
+
+ // since initialization plugins may be game-specific, ensure the plugin may be loaded for the active profile before proceeding
+ if (IsValidToLoadPlugin(pluginAssembly))
+ {
+ LoadDefinitionsFromAssembly(PluginLoadType.Initialize, pluginAssembly);
+
+ loadedPlugin.Status = PluginLoadStatus.Loaded;
+ break;
+ }
+
+ loadedPlugin.Status = PluginLoadStatus.LoadedInvalid;
+ break;
+
+ case PluginLoadType.Startup:
+ case PluginLoadType.Initialize:
+ LoadDefinitionsFromAssembly(loadType.Value, pluginAssembly);
+
+ loadedPlugin.Status = PluginLoadStatus.Loaded;
+ break;
+ }
+
+ // the assembly may now be stored within the plugin instance's Assembly property
+ loadedPlugin.Assembly = pluginAssembly;
+ }
+ catch (Exception e)
+ {
+ loadedPlugin.LoadException = e;
+ }
+
+ return loadedPlugin;
+ }
+
+ ///
+ /// Determines whether or not a plugin is valid for the active profile.
+ ///
+ /// The plugin assembly to be checked.
+ /// A bool determining whether or not the given plugin is valid for the active profile.
private bool IsValidToLoadPlugin(Assembly assembly)
{
+ if (assembly == null)
+ {
+ // return true to have the plugin "loaded," as if we were to return false, the plugin would be marked invalid
+ return true;
+ }
+
List validAttrs = new List();
List notValidAttrs = new List();
@@ -407,8 +382,10 @@ private bool IsValidToLoadPlugin(Assembly assembly)
foreach (var attr in notValidAttrs)
{
- if (ProfilesLibrary.DataVersion == attr.ProfileVersion)
+ if (ProfilesLibrary.IsLoaded((ProfileVersion)attr.ProfileVersion))
+ {
return false;
+ }
}
bool retVal = false;
@@ -420,7 +397,7 @@ private bool IsValidToLoadPlugin(Assembly assembly)
{
foreach (var attr in validAttrs)
{
- if (ProfilesLibrary.DataVersion == attr.ProfileVersion)
+ if (ProfilesLibrary.IsLoaded((ProfileVersion)attr.ProfileVersion))
{
retVal = true;
break;
@@ -431,31 +408,40 @@ private bool IsValidToLoadPlugin(Assembly assembly)
return retVal;
}
- // loads all the necessary definitions from a plugin based on the exported attributes.
+ ///
+ /// Loads all plugin definitions of a specified from a given assembly.
+ ///
+ /// The type of plugins to be located and loaded.
+ /// The assembly to be checked for plugin definitions.
private void LoadDefinitionsFromAssembly(PluginLoadType loadType, Assembly assembly)
{
+ if (assembly == null)
+ {
+ return;
+ }
+
foreach (var tmpAttr in assembly.GetCustomAttributes())
{
- if (managerType == PluginManagerType.ModManager && !(tmpAttr is RegisterCustomHandlerAttribute) && !(tmpAttr is RegisterExecutionAction) && !(tmpAttr is RegisterOptionsExtensionAttribute))
+ if (m_managerType == PluginManagerType.ModManager && !(tmpAttr is RegisterCustomHandlerAttribute) && !(tmpAttr is RegisterExecutionAction) && !(tmpAttr is RegisterOptionsExtensionAttribute))
continue;
if (loadType == PluginLoadType.Startup)
{
if (tmpAttr is RegisterProfileAttribute attr1)
{
- profiles.Add(((IProfile)Activator.CreateInstance(attr1.ProfileType)).CreateProfile());
+ m_profiles.Add(((IProfile)Activator.CreateInstance(attr1.ProfileType)).CreateProfile());
}
else if (tmpAttr is RegisterTypeOverrideAttribute attr4)
{
- typeOverrides.Add(attr4.LookupName.ToLower(), attr4.EditorType);
+ m_typeOverrides.Add(attr4.LookupName.ToLower(), attr4.EditorType);
}
else if (tmpAttr is RegisterGlobalTypeEditorAttribute attr3)
{
- globalTypEditors.Add(attr3.LookupName.ToLower(), attr3.EditorType);
+ m_globalTypeEditors.Add(attr3.LookupName.ToLower(), attr3.EditorType);
}
else if (tmpAttr is RegisterStartupActionAttribute attr2)
{
- startupActions.Add((StartupAction)Activator.CreateInstance(attr2.StartupActionType));
+ m_startupActions.Add((StartupAction)Activator.CreateInstance(attr2.StartupActionType));
}
}
else if (loadType == PluginLoadType.Initialize)
@@ -469,16 +455,16 @@ private void LoadDefinitionsFromAssembly(PluginLoadType loadType, Assembly assem
foreach (var subType in TypeLibrary.GetDerivedTypes(assetType))
{
string subName = subType.Name.ToLower();
- if (!definitions.ContainsKey(subName))
+ if (!m_definitions.ContainsKey(subName))
{
- definitions.Add(subName, definition);
+ m_definitions.Add(subName, definition);
}
}
string name = assetType.Name.ToLower();
- if (!definitions.ContainsKey(name))
+ if (!m_definitions.ContainsKey(name))
{
- definitions.Add(name, definition);
+ m_definitions.Add(name, definition);
}
}
else
@@ -487,9 +473,9 @@ private void LoadDefinitionsFromAssembly(PluginLoadType loadType, Assembly assem
AssetDefinition definition = (AssetDefinition)Activator.CreateInstance(attr1.AssetDefinitionType);
string name = attr1.LookupType.ToLower();
- if (!definitions.ContainsKey(name))
+ if (!m_definitions.ContainsKey(name))
{
- definitions.Add(name, definition);
+ m_definitions.Add(name, definition);
}
}
}
@@ -497,53 +483,53 @@ private void LoadDefinitionsFromAssembly(PluginLoadType loadType, Assembly assem
{
if (!attr2.MenuExtensionType.IsSubclassOf(typeof(MenuExtension)))
throw new Exception("Menu extensions must extend from MenuExtensions base class");
- menuExtensions.Add((MenuExtension)Activator.CreateInstance(attr2.MenuExtensionType));
+ m_menuExtensions.Add((MenuExtension)Activator.CreateInstance(attr2.MenuExtensionType));
}
else if (tmpAttr is RegisterOptionsExtensionAttribute attr5)
{
- if (attr5.ManagerType == managerType || attr5.ManagerType == PluginManagerType.Both)
+ if (attr5.ManagerType == m_managerType || attr5.ManagerType == PluginManagerType.Both)
{
if (!attr5.OptionsType.IsSubclassOf(typeof(OptionsExtension)))
throw new Exception("Option extensions must extend from OptionsExtension base class");
- optionsExtensions.Add(attr5.OptionsType);
+ m_optionsExtensions.Add(attr5.OptionsType);
}
}
else if (tmpAttr is RegisterThirdPartyDllAttribute attr6)
{
string dllname = attr6.DllName.ToLower();
- if (!thirdPartyDlls.Contains(dllname))
- thirdPartyDlls.Add(dllname);
+ if (!m_thirdPartyDlls.Contains(dllname))
+ m_thirdPartyDlls.Add(dllname);
}
else if (tmpAttr is RegisterLocalizedStringDatabaseAttribute attr7)
{
- if (localizedStringDatabaseType == null && attr7.LocalizedStringDatabaseType.GetInterface("ILocalizedStringDatabase") != null)
- localizedStringDatabaseType = attr7.LocalizedStringDatabaseType;
+ if (m_localizedStringDatabaseType == null && attr7.LocalizedStringDatabaseType.GetInterface("ILocalizedStringDatabase") != null)
+ m_localizedStringDatabaseType = attr7.LocalizedStringDatabaseType;
}
else if (tmpAttr is RegisterShaderAttribute attr8)
{
- if (!shaders.ContainsKey(attr8.KeyName))
- shaders.Add(attr8.KeyName, new ShaderDefinition[2]);
+ if (!m_shaders.ContainsKey(attr8.KeyName))
+ m_shaders.Add(attr8.KeyName, new ShaderDefinition[2]);
- if ((attr8.ShaderType == ShaderType.VertexShader || attr8.ShaderType == ShaderType.ComputeShader) && shaders[attr8.KeyName][0] == null)
- shaders[attr8.KeyName][0] = new ShaderDefinition(assembly, attr8.ShaderType, attr8.ResourceName);
- if (attr8.ShaderType == ShaderType.PixelShader && shaders[attr8.KeyName][1] == null)
- shaders[attr8.KeyName][1] = new ShaderDefinition(assembly, attr8.ShaderType, attr8.ResourceName);
+ if ((attr8.ShaderType == ShaderType.VertexShader || attr8.ShaderType == ShaderType.ComputeShader) && m_shaders[attr8.KeyName][0] == null)
+ m_shaders[attr8.KeyName][0] = new ShaderDefinition(assembly, attr8.ShaderType, attr8.ResourceName);
+ if (attr8.ShaderType == ShaderType.PixelShader && m_shaders[attr8.KeyName][1] == null)
+ m_shaders[attr8.KeyName][1] = new ShaderDefinition(assembly, attr8.ShaderType, attr8.ResourceName);
}
else if (tmpAttr is RegisterTabExtensionAttribute attr9)
{
if (!attr9.TabExtensionType.IsSubclassOf(typeof(TabExtension)))
throw new Exception("Tab extensions must extend from MenuExtensions base class");
- tabExtensions.Add((TabExtension)Activator.CreateInstance(attr9.TabExtensionType));
+ m_tabExtensions.Add((TabExtension)Activator.CreateInstance(attr9.TabExtensionType));
}
else if (tmpAttr is RegisterDataExplorerContextMenuAttribute attr10)
{
if (!attr10.ContextMenuItemExtensionType.IsSubclassOf(typeof(DataExplorerContextMenuExtension)))
throw new Exception("Data Explorer context menu item extensions must extend from ContextMenuExtensions base class");
- contextMenuItemExtensions.Add((DataExplorerContextMenuExtension)Activator.CreateInstance(attr10.ContextMenuItemExtensionType));
+ m_contextMenuItemExtensions.Add((DataExplorerContextMenuExtension)Activator.CreateInstance(attr10.ContextMenuItemExtensionType));
}
else if (tmpAttr is RegisterExecutionAction attr11)
{
- executionActions.Add((ExecutionAction)Activator.CreateInstance(attr11.ExecutionActionType));
+ m_executionActions.Add((ExecutionAction)Activator.CreateInstance(attr11.ExecutionActionType));
}
else if (tmpAttr is RegisterCustomHandlerAttribute attr)
{
@@ -554,21 +540,21 @@ private void LoadDefinitionsFromAssembly(PluginLoadType loadType, Assembly assem
{
foreach (var subType in TypeLibrary.GetDerivedTypes(assetType))
{
- customHandlers.Add((uint)Fnv1.HashString(subType.Name.ToLower()), attr.HandlerClassType);
+ m_customHandlers.Add((uint)Fnv1.HashString(subType.Name.ToLower()), attr.HandlerClassType);
}
- customHandlers.Add((uint)Fnv1.HashString(assetType.Name.ToLower()), attr.HandlerClassType);
+ m_customHandlers.Add((uint)Fnv1.HashString(assetType.Name.ToLower()), attr.HandlerClassType);
}
}
else if (attr.HandlerType == CustomHandlerType.Res)
{
- resCustomHandlers.Add(attr.ResType, attr.HandlerClassType);
+ m_resCustomHandlers.Add(attr.ResType, attr.HandlerClassType);
}
}
else if (tmpAttr is RegisterUserShaderAttribute registerUserShaderAttribute)
{
if (registerUserShaderAttribute != null)
{
- userShaders.Add(registerUserShaderAttribute.XmlDescriptor + "," + registerUserShaderAttribute.ShaderName);
+ m_userShaders.Add(registerUserShaderAttribute.XmlDescriptor + "," + registerUserShaderAttribute.ShaderName);
continue;
}
}
diff --git a/FrostyPlugin/PluginManagerType.cs b/FrostyPlugin/PluginManagerType.cs
new file mode 100644
index 000000000..e58c33c12
--- /dev/null
+++ b/FrostyPlugin/PluginManagerType.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Frosty.Core
+{
+ ///
+ /// Describes the context in which the plugin manager is loading.
+ ///
+ public enum PluginManagerType
+ {
+ ///
+ /// The plugin is loading into the editor.
+ ///
+ Editor,
+
+ ///
+ /// The plugin is loading into the mod manager.
+ ///
+ ModManager,
+
+ ///
+ /// The plugin is loading for both the editor and mod manager.
+ ///
+ Both
+ }
+}
diff --git a/FrostyPlugin/ShaderDefinition.cs b/FrostyPlugin/ShaderDefinition.cs
new file mode 100644
index 000000000..f33889669
--- /dev/null
+++ b/FrostyPlugin/ShaderDefinition.cs
@@ -0,0 +1,47 @@
+using Frosty.Core.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Frosty.Core
+{
+ ///
+ /// Represents a shader loaded from a plugin
+ ///
+ public sealed class ShaderDefinition
+ {
+ ///
+ /// Gets the plugin in which the shader is located.
+ ///
+ /// The that represents the plugin.
+ public Assembly Assembly { get; private set; }
+
+ ///
+ /// Gets the name of the shader resource file in the format of Namespace.ResourceName.
+ ///
+ /// The name of the shader resource file.
+ public string ResourceName { get; set; }
+
+ ///
+ /// Gets the type of shader.
+ ///
+ /// The type of shader.
+ public ShaderType ShaderType { get; set; }
+
+ ///
+ /// Initializes a new instance of the class with the plugin, shader type, and resource name.
+ ///
+ /// The plugin in which the shader is located.
+ /// The type of shader.
+ /// The resource name of the shader in the format of Namespace.ResourceName.
+ public ShaderDefinition(Assembly plugin, ShaderType type, string resourceName)
+ {
+ Assembly = plugin;
+ ShaderType = type;
+ ResourceName = resourceName;
+ }
+ }
+}
diff --git a/Plugins/BlankPlugin/BuildDate.txt b/Plugins/BlankPlugin/BuildDate.txt
index c707bf521..19c9a7215 100644
--- a/Plugins/BlankPlugin/BuildDate.txt
+++ b/Plugins/BlankPlugin/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 15:03:38.03
\ No newline at end of file
+Wed 10/12/2022 16:58:29.14
diff --git a/Plugins/LaunchPlatformPlugin/BuildDate.txt b/Plugins/LaunchPlatformPlugin/BuildDate.txt
index 72896968a..407eca98b 100644
--- a/Plugins/LaunchPlatformPlugin/BuildDate.txt
+++ b/Plugins/LaunchPlatformPlugin/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 15:03:39.50
\ No newline at end of file
+Wed 10/12/2022 16:58:29.84
From d68d820a375cc4b438c4106fde1198ca41819ada Mon Sep 17 00:00:00 2001
From: NM <35472796+NM-20@users.noreply.github.com>
Date: Wed, 12 Oct 2022 18:34:56 -0400
Subject: [PATCH 2/3] [Core] Fixed GetPluginAssembly exception with null
assemblies
---
FrostyEditor/BuildDate.txt | 2 +-
FrostyModManager/BuildDate.txt | 2 +-
FrostyPlugin/PluginManager.cs | 5 ++++-
Plugins/BlankPlugin/BuildDate.txt | 2 +-
Plugins/LaunchPlatformPlugin/BuildDate.txt | 2 +-
5 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/FrostyEditor/BuildDate.txt b/FrostyEditor/BuildDate.txt
index e79ce8caf..15abc4b2a 100644
--- a/FrostyEditor/BuildDate.txt
+++ b/FrostyEditor/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 17:36:47.21
+Wed 10/12/2022 18:33:23.69
diff --git a/FrostyModManager/BuildDate.txt b/FrostyModManager/BuildDate.txt
index e79ce8caf..15abc4b2a 100644
--- a/FrostyModManager/BuildDate.txt
+++ b/FrostyModManager/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 17:36:47.21
+Wed 10/12/2022 18:33:23.69
diff --git a/FrostyPlugin/PluginManager.cs b/FrostyPlugin/PluginManager.cs
index c39c41736..a6c3a3750 100644
--- a/FrostyPlugin/PluginManager.cs
+++ b/FrostyPlugin/PluginManager.cs
@@ -233,8 +233,11 @@ public Assembly GetPluginAssembly(string name)
{
foreach (var plugin in m_plugins)
{
- if (plugin.Assembly.GetName().Name.Equals(name, StringComparison.OrdinalIgnoreCase))
+ // if the plugin does not have an assigned assembly, skip it
+ if (plugin.Assembly?.GetName().Name.Equals(name, StringComparison.OrdinalIgnoreCase) ?? false)
+ {
return plugin.Assembly;
+ }
}
return null;
}
diff --git a/Plugins/BlankPlugin/BuildDate.txt b/Plugins/BlankPlugin/BuildDate.txt
index 19c9a7215..235648959 100644
--- a/Plugins/BlankPlugin/BuildDate.txt
+++ b/Plugins/BlankPlugin/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 16:58:29.14
+Wed 10/12/2022 18:33:19.61
diff --git a/Plugins/LaunchPlatformPlugin/BuildDate.txt b/Plugins/LaunchPlatformPlugin/BuildDate.txt
index 407eca98b..26b325f51 100644
--- a/Plugins/LaunchPlatformPlugin/BuildDate.txt
+++ b/Plugins/LaunchPlatformPlugin/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 16:58:29.84
+Wed 10/12/2022 18:33:20.54
From 8345be8adb972720d9dbfaa80db9d554d1e39d18 Mon Sep 17 00:00:00 2001
From: NM <35472796+NM-20@users.noreply.github.com>
Date: Mon, 24 Oct 2022 18:47:55 -0400
Subject: [PATCH 3/3] [Editor & ModManager] Adjusted loaded plugins list to use
SVG icons and slightly resized editor MainWindow
---
FrostyControls/FrostyControls.csproj | 4 +
FrostyControls/Themes/Generic.xaml | 2848 +++++++++++++++-----
FrostyControls/Themes/Icons.xaml | 15 +
FrostyEditor/BuildDate.txt | 2 +-
FrostyEditor/Windows/MainWindow.xaml | 47 +-
FrostyModManager/BuildDate.txt | 2 +-
FrostyModManager/Windows/MainWindow.xaml | 43 +-
FrostyPlugin/FrostyCore.csproj | 5 -
FrostyPlugin/Images/Cross_White.png | Bin 419 -> 0 bytes
FrostyPlugin/Images/Invalid_White.png | Bin 270 -> 0 bytes
FrostyPlugin/Images/Tick_White.png | Bin 430 -> 0 bytes
Plugins/BlankPlugin/BuildDate.txt | 2 +-
Plugins/LaunchPlatformPlugin/BuildDate.txt | 2 +-
13 files changed, 2176 insertions(+), 794 deletions(-)
create mode 100644 FrostyControls/Themes/Icons.xaml
delete mode 100644 FrostyPlugin/Images/Cross_White.png
delete mode 100644 FrostyPlugin/Images/Invalid_White.png
delete mode 100644 FrostyPlugin/Images/Tick_White.png
diff --git a/FrostyControls/FrostyControls.csproj b/FrostyControls/FrostyControls.csproj
index 0d33e1e5d..65a1384dc 100644
--- a/FrostyControls/FrostyControls.csproj
+++ b/FrostyControls/FrostyControls.csproj
@@ -88,6 +88,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
diff --git a/FrostyControls/Themes/Generic.xaml b/FrostyControls/Themes/Generic.xaml
index 7d929fc41..34713be43 100644
--- a/FrostyControls/Themes/Generic.xaml
+++ b/FrostyControls/Themes/Generic.xaml
@@ -1,73 +1,120 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
+
-
+
-
+
-
-
-
-
+
+
@@ -453,45 +727,69 @@
-
+
-
+
-
-
-
-
+
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -1243,10 +2101,13 @@
-
+
-
+
@@ -1254,7 +2115,7 @@
-
+
@@ -1265,7 +2126,11 @@
-
+
@@ -1273,52 +2138,111 @@
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
+
+
+
-
-
+
+
@@ -1336,32 +2260,72 @@
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
@@ -1373,12 +2337,20 @@
-
-
-
+
+
+
-
-
+
+
@@ -1388,56 +2360,100 @@
-
+
-
-
-
-
-
+
+
+
diff --git a/FrostyControls/Themes/Icons.xaml b/FrostyControls/Themes/Icons.xaml
new file mode 100644
index 000000000..e0f9cb347
--- /dev/null
+++ b/FrostyControls/Themes/Icons.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FrostyEditor/BuildDate.txt b/FrostyEditor/BuildDate.txt
index 15abc4b2a..4afa8787c 100644
--- a/FrostyEditor/BuildDate.txt
+++ b/FrostyEditor/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 18:33:23.69
+Mon 10/24/2022 18:29:27.22
diff --git a/FrostyEditor/Windows/MainWindow.xaml b/FrostyEditor/Windows/MainWindow.xaml
index bdc828c55..4a5929f08 100644
--- a/FrostyEditor/Windows/MainWindow.xaml
+++ b/FrostyEditor/Windows/MainWindow.xaml
@@ -14,8 +14,8 @@
MinWidth="500"
MinHeight="250"
Icon="/FrostyEditor;component/AppIcon.ico"
- Height="720"
- Width="1280"
+ Height="802"
+ Width="1448"
FrostyLoaded="FrostyWindow_Loaded"
WindowState="Maximized"
Title="Frosty Editor"
@@ -720,44 +720,47 @@
-
+ Height="24"
+ HorizontalAlignment="Center">
+
-
-
-
+
-
-
+
-
-
+
diff --git a/FrostyModManager/BuildDate.txt b/FrostyModManager/BuildDate.txt
index 15abc4b2a..4afa8787c 100644
--- a/FrostyModManager/BuildDate.txt
+++ b/FrostyModManager/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 18:33:23.69
+Mon 10/24/2022 18:29:27.22
diff --git a/FrostyModManager/Windows/MainWindow.xaml b/FrostyModManager/Windows/MainWindow.xaml
index 214699021..894402d11 100644
--- a/FrostyModManager/Windows/MainWindow.xaml
+++ b/FrostyModManager/Windows/MainWindow.xaml
@@ -996,44 +996,47 @@
-
+ Height="24"
+ HorizontalAlignment="Center">
+
-
-
-
+
-
-
+
-
-
+
diff --git a/FrostyPlugin/FrostyCore.csproj b/FrostyPlugin/FrostyCore.csproj
index 037024d96..e46cb019c 100644
--- a/FrostyPlugin/FrostyCore.csproj
+++ b/FrostyPlugin/FrostyCore.csproj
@@ -421,10 +421,5 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/FrostyPlugin/Images/Cross_White.png b/FrostyPlugin/Images/Cross_White.png
deleted file mode 100644
index 1d3a3480364b6fc01bf887aa02db17bca535e928..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 419
zcmV;U0bKrxP)p-dDg75v}BX
z1y~VPLh{O&e29P)5y9j>0kNyNiNlF}k}EJ(oCp_h?#>_Dg4E;|TZtVcz!2XyabnS^>T%wTTtUk=QEYySGodMnJAu)xSPQwQ!_8OsM=J9(7%+>8zJJLnWx@E4cW)izom(swS1RU~
zD=?}w)G;nG^kKMokLi7T3RjBg@07G~|G526t(X`*B?V4By?Ewa;e=Vaaw?*~R!k77
z3qQtu;_KQwlb^~SF6=eW6i$eL{MN?tUUdS;n#Ri0LGy5AA`Hat!uyJS)%ULnfylfSB&BcpzNb2O81>sIE3(H_-eI7!18TLIL7H
z%*MIA;sA(gx1?bNMK+K=cX#}7g*ZeO4wGmwf&Vacj=3an8|4$pF07*qoM6N<$f(5O>o&W#<
diff --git a/Plugins/BlankPlugin/BuildDate.txt b/Plugins/BlankPlugin/BuildDate.txt
index 235648959..894b7cbf1 100644
--- a/Plugins/BlankPlugin/BuildDate.txt
+++ b/Plugins/BlankPlugin/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 18:33:19.61
+Mon 10/24/2022 18:24:24.42
diff --git a/Plugins/LaunchPlatformPlugin/BuildDate.txt b/Plugins/LaunchPlatformPlugin/BuildDate.txt
index 26b325f51..972fd6236 100644
--- a/Plugins/LaunchPlatformPlugin/BuildDate.txt
+++ b/Plugins/LaunchPlatformPlugin/BuildDate.txt
@@ -1 +1 @@
-Wed 10/12/2022 18:33:20.54
+Mon 10/24/2022 18:24:24.86