Skip to content

Commit

Permalink
Merge pull request #343 from Monitor221hz/plugin-loading
Browse files Browse the repository at this point in the history
[Feature]: Rudimentary support for loading custom patcher plugins (injected into configuration selection menu on load)
  • Loading branch information
Monitor221hz authored Nov 6, 2024
2 parents 9dfb3ec + c15dd1a commit b273ebe
Show file tree
Hide file tree
Showing 56 changed files with 647 additions and 222 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# Plugin-specific files
[Pp]lugin.json

# User-specific files
*.rsuser
*.suo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Text;
using System.Threading.Tasks;

namespace Pandora.Patch.IOManagers;
namespace Pandora.API.Patch.IOManagers;
public interface IDataExporter<T>
{
public DirectoryInfo ExportDirectory { get; set; }
Expand All @@ -19,9 +19,4 @@ public bool ExportParallel(IEnumerable<T> objs)
return success;
}
}
public interface IMetaDataExporter<T> : IDataExporter<T>
{
public void LoadMetaData();
public void SaveMetaData(IEnumerable<T> collection);
}

10 changes: 10 additions & 0 deletions Pandora API/IOManagers/IMetaDataExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace Pandora.API.Patch.IOManagers;

public interface IMetaDataExporter<T> : IDataExporter<T>
{
public void LoadMetaData();
public void SaveMetaData(IEnumerable<T> collection);
}

10 changes: 10 additions & 0 deletions Pandora API/Pandora API.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Pandora.API</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
11 changes: 11 additions & 0 deletions Pandora API/Patch.Engine.Config/IEngineConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Pandora.API.Patch.Engine.Config;

public interface IEngineConfiguration
{
string Name { get; }

string Description { get; }

public IPatcher Patcher { get; }

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Pandora.Core;
using System.ComponentModel;

namespace Pandora.Core.Engine.Configs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pandora.API.Patch.Engine.Config;
public interface IEngineConfigurationFactory
{
public string Name { get; }
Expand Down
17 changes: 17 additions & 0 deletions Pandora API/Patch.Engine.Config/IEngineConfigurationPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pandora.API.Patch.Engine.Config;
public interface IEngineConfigurationPlugin
{
public enum OptionFlags
{
None = 0,
HidePatches = 1,
}
public string MenuPath { get; }
public IEngineConfigurationFactory Factory { get; }
}
10 changes: 10 additions & 0 deletions Pandora API/Patch.Engine.Plugins/IPluginInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

namespace Pandora.API.Patch.Engine.Plugins;

public interface IPluginInfo
{
public const string FILE_HEADER = "plugin";
string Name { get; set; }
string Author { get; set; }
string Path { get; set; }
}
10 changes: 10 additions & 0 deletions Pandora API/Patch.Engine.Plugins/IPluginLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Pandora.API.Patch.Engine.Plugins;
using System.IO;
using System.Reflection;

namespace Pandora.Models.Patch.Engine.Plugins;
public interface IPluginLoader
{
Assembly LoadPlugin(DirectoryInfo directory, IPluginInfo pluginInfo);
bool TryLoadMetadata(DirectoryInfo directory, out IPluginInfo? pluginInfo);
}
13 changes: 13 additions & 0 deletions Pandora API/Patch.Engine.Plugins/PluginInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pandora.API.Patch.Engine.Plugins;
public class PluginInfo : IPluginInfo
{
public string Name { get; set; }

Check warning on line 10 in Pandora API/Patch.Engine.Plugins/PluginInfo.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
public string Author { get; set; }

Check warning on line 11 in Pandora API/Patch.Engine.Plugins/PluginInfo.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Author' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
public string Path { get; set; }

Check warning on line 12 in Pandora API/Patch.Engine.Plugins/PluginInfo.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Non-nullable property 'Path' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
}
32 changes: 32 additions & 0 deletions Pandora API/Patch/IModInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Pandora.API.Patch;

/// <summary>
/// Strongly recommended to implement GetHashCode() in addition to IEquatable.
/// </summary>
public interface IModInfo : IEquatable<IModInfo>
{
public enum ModFormat
{
FNIS,
Nemesis,
Pandora
}

public string Name { get; }

public string Author { get; }

public string URL { get; }

public string Code { get; }

public Version Version { get; }

public DirectoryInfo Folder { get; }

public ModFormat Format { get; }

public bool Active { get; set; }

public uint Priority { get; set; }
}
36 changes: 36 additions & 0 deletions Pandora API/Patch/IPatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Pandora.API.Patch;

public interface IPatcher
{
[Flags]
public enum PatcherFlags
{
None = 0,
PreloadFailed = 1 << 1,
UpdateFailed = 1 << 2,
LaunchFailed = 1 << 3,
Success = ~(PreloadFailed | UpdateFailed | LaunchFailed)
}
public PatcherFlags Flags { get; }
public string GetVersionString();
public Version GetVersion();
public void SetTarget(List<IModInfo> mods);

public Task PreloadAsync();

public void Update();

public void Run();

public string GetPostRunMessages();

public string GetFailureMessages();

public Task<bool> UpdateAsync();

public Task<bool> RunAsync();

public void SetOutputPath(DirectoryInfo directoryInfo);

public void SetOutputPath(string outputPath) => SetOutputPath(new DirectoryInfo(outputPath));
}
2 changes: 1 addition & 1 deletion Pandora Behaviour Engine/Data/IModInfoProvider.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Pandora.Core;

using Pandora.API.Patch;
namespace Pandora.MVVM.Data;

public interface IModInfoProvider
Expand Down
2 changes: 1 addition & 1 deletion Pandora Behaviour Engine/Data/NemesisModInfoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Text;
using System.Threading.Tasks;
using Pandora.Core;

using Pandora.API.Patch;
namespace Pandora.MVVM.Data;

public class NemesisModInfoProvider : IModInfoProvider
Expand Down
3 changes: 2 additions & 1 deletion Pandora Behaviour Engine/Data/PandoraModInfoProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Pandora.Core;
using Pandora.API.Patch;
using Pandora.Core;

using System;
using System.Collections.Generic;
Expand Down
1 change: 1 addition & 0 deletions Pandora Behaviour Engine/Models/FNISModInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Pandora.API.Patch;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down
42 changes: 0 additions & 42 deletions Pandora Behaviour Engine/Models/IModInfo.cs

This file was deleted.

1 change: 1 addition & 0 deletions Pandora Behaviour Engine/Models/NemesisModInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Pandora.API.Patch;
using Pandora.Core;

namespace Pandora.Core;
Expand Down
3 changes: 2 additions & 1 deletion Pandora Behaviour Engine/Models/PandoraModInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Pandora.Core;
using Pandora.API.Patch;
using Pandora.Core;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down
58 changes: 56 additions & 2 deletions Pandora Behaviour Engine/Models/Patch/Engine/BehaviourEngine.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Microsoft.Win32;
using Pandora.API.Patch;
using Pandora.API.Patch.Engine.Config;
using Pandora.Core.Engine.Configs;
using System;
using System.Collections.Generic;
Expand All @@ -7,17 +9,66 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

using System.Reflection;
using Pandora.Models.Patch.Engine;
using Pandora.Models.Patch.Engine.Plugins;
using System.Diagnostics;
namespace Pandora.Core
{
public class BehaviourEngine
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public static readonly DirectoryInfo AssemblyDirectory = new FileInfo(System.Reflection.Assembly.GetEntryAssembly()!.Location).Directory!;

public static readonly List<IEngineConfigurationPlugin> EngineConfigurations = new List<IEngineConfigurationPlugin>();

public readonly static DirectoryInfo? SkyrimGameDirectory;
private static IEnumerable<IEngineConfigurationPlugin> CreateConfigurations(Assembly assembly)
{
foreach(Type type in assembly.GetTypes())
{
Debug.WriteLine(type.Module.FullyQualifiedName);
if (typeof(IEngineConfigurationPlugin).IsAssignableFrom(type))
{
IEngineConfigurationPlugin? result = Activator.CreateInstance(type) as IEngineConfigurationPlugin;
if (result != null)
{
yield return result;
}
}
}
yield break;
}
private static void LoadPlugins()
{
var pluginLoader = new JsonPluginLoader();
var pluginsDirectory = AssemblyDirectory.CreateSubdirectory("Plugins");
Assembly assembly;
foreach (DirectoryInfo pluginDirectory in pluginsDirectory.EnumerateDirectories())
{
if (!pluginLoader.TryLoadMetadata(pluginDirectory, out var pluginInfo))
{
continue;
}

try
{
assembly = pluginLoader.LoadPlugin(pluginDirectory, pluginInfo);
EngineConfigurations.AddRange(CreateConfigurations(assembly));
}
catch
{

}
}
}
private void ReadSkyrimPath()
{

}
static BehaviourEngine()
{
LoadPlugins();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var subKey = "SOFTWARE\\Wow6432Node\\Bethesda Softworks\\Skyrim Special Edition";
Expand Down Expand Up @@ -64,14 +115,17 @@ public BehaviourEngine(IEngineConfiguration configuration)
}
public void Launch(List<IModInfo> mods)
{

logger.Info($"Launching with configuration {Configuration.Name}");
logger.Info($"Launching with patcher {Configuration.Patcher.GetVersionString()}");
Configuration.Patcher.SetTarget(mods);
Configuration.Patcher.Update();
Configuration.Patcher.Run();
}

public async Task<bool> LaunchAsync(List<IModInfo> mods)
{
logger.Info($"Launching with configuration {Configuration.Name}");
logger.Info($"Launching with patcher version {Configuration.Patcher.GetVersionString()}");
Configuration.Patcher.SetTarget(mods);

if (!OutputPath.Exists) OutputPath.Create();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Pandora.Core;
using Pandora.API.Patch;
using Pandora.API.Patch.Engine.Config;
using Pandora.Core;
using Pandora.Core.IOManagers;
using Pandora.Core.Patchers;
using Pandora.Core.Patchers.Skyrim;
Expand Down
Loading

0 comments on commit b273ebe

Please sign in to comment.