diff --git a/OpenPuppet.Plugins/Manager.cs b/OpenPuppet.Plugins/Manager.cs
new file mode 100644
index 0000000..eaa8592
--- /dev/null
+++ b/OpenPuppet.Plugins/Manager.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OpenPuppet.Plugins
+{
+ public static class Manager
+ {
+ ///
+ /// Installs a plugin from a path, the path can either be a directory
+ /// or a ZIP file.
+ ///
+ /// The path to directory/ZIP file
+ public static void InstallPlugin(string path)
+ {
+ if (Directory.Exists(path)) InstallPluginDir(path);
+ else InstallPluginArchive(path);
+ }
+
+ public static async Task InstallPluginAsync(string path)
+ {
+ return;
+ }
+
+ static internal void InstallPluginDir(string path)
+ {
+
+ }
+
+ static internal void InstallPluginArchive(string path)
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenPuppet.Plugins/Metadata.cs b/OpenPuppet.Plugins/Metadata.cs
new file mode 100644
index 0000000..6a52b5d
--- /dev/null
+++ b/OpenPuppet.Plugins/Metadata.cs
@@ -0,0 +1,7 @@
+namespace OpenPuppet.Plugins
+{
+ public static class Metadata
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/OpenPuppet.Plugins/OpenPuppet.Plugins.csproj b/OpenPuppet.Plugins/OpenPuppet.Plugins.csproj
new file mode 100644
index 0000000..44562a6
--- /dev/null
+++ b/OpenPuppet.Plugins/OpenPuppet.Plugins.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/OpenPuppet.Plugins/Path.cs b/OpenPuppet.Plugins/Path.cs
new file mode 100644
index 0000000..c686d20
--- /dev/null
+++ b/OpenPuppet.Plugins/Path.cs
@@ -0,0 +1,50 @@
+using OpenPuppet.DataTypes.Plugin;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+
+namespace OpenPuppet.Plugins
+{
+ public static class Path
+ {
+ internal static string? InstallPath
+ {
+ get
+ {
+ return System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ }
+ }
+
+ public static string? PluginPath
+ {
+ get
+ {
+ return InstallPath != null ? System.IO.Path.Combine(InstallPath, "Plugins") : null;
+ }
+ }
+
+ public static string SafePluginName(string name)
+ {
+ name = name.ToLower().Replace(' ', '-');
+ name = Regex.Replace(name, @"[^a-zA-Z0-9]", "");
+
+ return name;
+ }
+
+ public static string? GetPluginPath(string name)
+ {
+ if (PluginPath == null) return null;
+ return System.IO.Path.Combine(PluginPath, SafePluginName(name));
+ }
+
+ public static string? GetPluginPath(PluginMetadata metadata)
+ {
+ return GetPluginPath(metadata.Name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenPuppet.sln b/OpenPuppet.sln
index 03980c6..6d805c8 100644
--- a/OpenPuppet.sln
+++ b/OpenPuppet.sln
@@ -7,6 +7,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenPuppet", "src\OpenPuppe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenPuppet.Tests", "src\OpenPuppet.Tests\OpenPuppet.Tests.csproj", "{E2D6A937-6D8B-43B4-9EA8-6292872C2224}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenPuppet.DataTypes", "src\OpenPuppet.DataTypes\OpenPuppet.DataTypes.csproj", "{E4A8B804-ECED-4140-8B30-66B7842FD863}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenPuppet.Plugins", "OpenPuppet.Plugins\OpenPuppet.Plugins.csproj", "{D1EE7937-72B4-4A1A-9B9B-EF1759027462}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +25,14 @@ Global
{E2D6A937-6D8B-43B4-9EA8-6292872C2224}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2D6A937-6D8B-43B4-9EA8-6292872C2224}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2D6A937-6D8B-43B4-9EA8-6292872C2224}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4A8B804-ECED-4140-8B30-66B7842FD863}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4A8B804-ECED-4140-8B30-66B7842FD863}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4A8B804-ECED-4140-8B30-66B7842FD863}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4A8B804-ECED-4140-8B30-66B7842FD863}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1EE7937-72B4-4A1A-9B9B-EF1759027462}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1EE7937-72B4-4A1A-9B9B-EF1759027462}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1EE7937-72B4-4A1A-9B9B-EF1759027462}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1EE7937-72B4-4A1A-9B9B-EF1759027462}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/OpenPuppet.DataTypes/OpenPuppet.DataTypes.csproj b/src/OpenPuppet.DataTypes/OpenPuppet.DataTypes.csproj
new file mode 100644
index 0000000..fa71b7a
--- /dev/null
+++ b/src/OpenPuppet.DataTypes/OpenPuppet.DataTypes.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/src/OpenPuppet.DataTypes/Plugin.cs b/src/OpenPuppet.DataTypes/Plugin.cs
new file mode 100644
index 0000000..b8276e9
--- /dev/null
+++ b/src/OpenPuppet.DataTypes/Plugin.cs
@@ -0,0 +1,31 @@
+namespace OpenPuppet.DataTypes.Plugin
+{
+ ///
+ /// Plugin interface
+ ///
+ public interface IPlugin
+ {
+ ///
+ /// The plugin ID
+ ///
+ public string PluginID { get; set; }
+
+ ///
+ /// OnInitialized
+ /// This is called when the plugin is loaded, use this to prepare the plugin
+ ///
+ abstract void OnInitialized();
+ }
+
+ ///
+ /// Plugin metadata file
+ ///
+ public class PluginMetadata
+ {
+ public string Name { get; set; } = string.Empty;
+ public string Description { get; set; } = string.Empty;
+ public string Author { get; set; } = string.Empty;
+ public string Version { get; set; } = string.Empty;
+ public string Icon { get; set; } = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/src/OpenPuppet.Tests/OpenPuppet.Tests.csproj b/src/OpenPuppet.Tests/OpenPuppet.Tests.csproj
index 9c5b30a..7eb7cbd 100644
--- a/src/OpenPuppet.Tests/OpenPuppet.Tests.csproj
+++ b/src/OpenPuppet.Tests/OpenPuppet.Tests.csproj
@@ -16,6 +16,11 @@
+
+
+
+
+
diff --git a/src/OpenPuppet.Tests/Plugins/Path.cs b/src/OpenPuppet.Tests/Plugins/Path.cs
new file mode 100644
index 0000000..35ede98
--- /dev/null
+++ b/src/OpenPuppet.Tests/Plugins/Path.cs
@@ -0,0 +1,29 @@
+namespace OpenPuppet.Tests.Plugins
+{
+ public class Path
+ {
+ [Fact]
+ public void TestPluginName()
+ {
+ Assert.NotEqual(
+ "a-b-c-d",
+ OpenPuppet.Plugins.Path.SafePluginName(
+ @"a B
+`¦¬!" + '"' + @"@£$%^&*()_+-=[]{};:'@#~,./<>?\| C d"
+ )
+ );
+ }
+
+ [Fact]
+ public void TestPluginPath()
+ {
+ Assert.EndsWith(
+ "a-b-c-d",
+ OpenPuppet.Plugins.Path.GetPluginPath(
+ @"a B
+`¦¬!" + '"' + @"@£$%^&*()_+-=[]{};:'@#~,./<>?\| C d"
+ )
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenPuppet.Tests/UnitTest1.cs b/src/OpenPuppet.Tests/UnitTest1.cs
deleted file mode 100644
index 3ccfe2c..0000000
--- a/src/OpenPuppet.Tests/UnitTest1.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace OpenPuppet.Tests
-{
- public class UnitTest1
- {
- [Fact]
- public void Test1()
- {
-
- }
- }
-}
\ No newline at end of file
diff --git a/src/OpenPuppet/OpenPuppet.csproj b/src/OpenPuppet/OpenPuppet.csproj
index f9c525c..e14345f 100644
--- a/src/OpenPuppet/OpenPuppet.csproj
+++ b/src/OpenPuppet/OpenPuppet.csproj
@@ -17,6 +17,8 @@
+
+
PreserveNewest