-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
283 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
Aurora.Game.Plugins.LunarClient.Test/Aurora.Game.Plugins.LunarClient.Test.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup Label="Project"> | ||
<OutputType>WinExe</OutputType> | ||
<TargetFramework>net5.0</TargetFramework> | ||
<GenerateProgramFile>false</GenerateProgramFile> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
<ItemGroup Label="Project References"> | ||
<ProjectReference Include="..\Aurora.Game.Plugins.LunarClient\Aurora.Game.Plugins.LunarClient.csproj" /> | ||
</ItemGroup> | ||
<ItemGroup Label="Package References"> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> | ||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" /> | ||
</ItemGroup> | ||
</Project> |
13 changes: 13 additions & 0 deletions
13
Aurora.Game.Plugins.LunarClient/Aurora.Game.Plugins.LunarClient.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Library</OutputType> | ||
<TargetFramework>net5.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Aurora.Game\Aurora.Game.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using Aurora.Game.API; | ||
|
||
namespace Aurora.Game.Plugins.LunarClient | ||
{ | ||
public class LunarClientPlugin : Plugin | ||
{ | ||
public override PluginType PluginType => PluginType.LauncherContent; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Aurora.Game.API | ||
{ | ||
public abstract class Plugin | ||
{ | ||
public abstract PluginType PluginType { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using osu.Framework; | ||
using osu.Framework.Extensions.ObjectExtensions; | ||
using osu.Framework.Logging; | ||
using osu.Framework.Platform; | ||
|
||
namespace Aurora.Game.API | ||
{ | ||
/// <summary> | ||
/// Instanced plugin loading class. | ||
/// </summary> | ||
public class PluginLoader : IDisposable | ||
{ | ||
public const string PLUGIN_LIBRARY_PREFIX = "Aurora.Game.Plugins"; | ||
|
||
public readonly Dictionary<Assembly, Type> LoadedAssemblies = new(); | ||
|
||
public List<Plugin> LoadedPlugins = new(); | ||
|
||
private readonly Storage? storage; | ||
|
||
public PluginLoader(Storage? storage) | ||
{ | ||
this.storage = storage; | ||
} | ||
|
||
public void LoadPlugins() | ||
{ | ||
loadFromDisk(); | ||
|
||
AppDomain.CurrentDomain.AssemblyResolve += resolvePluginDependencyAssembly; | ||
|
||
Storage? pluginStorage = storage?.GetStorageForDirectory("plugins"); | ||
|
||
if (pluginStorage != null) | ||
loadUserPlugins(pluginStorage); | ||
|
||
LoadedPlugins.Clear(); | ||
LoadedPlugins.AddRange(LoadedAssemblies.Values | ||
.Select(x => Activator.CreateInstance(x) as Plugin) | ||
.Where(x => x is not null) | ||
.Select(x => x.AsNonNull()) | ||
.ToList()); | ||
} | ||
|
||
private void loadFromDisk() | ||
{ | ||
try | ||
{ | ||
string[] files = Directory.GetFiles(RuntimeInfo.StartupDirectory, $"{PLUGIN_LIBRARY_PREFIX}.*.dll"); | ||
|
||
foreach (string file in files.Where(x => !Path.GetFileName(x).Contains("Tests"))) | ||
loadPluginFromFile(file); | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Error(e, $"Could not load plug-in from directory {RuntimeInfo.StartupDirectory}"); | ||
} | ||
} | ||
|
||
private void loadPluginFromFile(string file) | ||
{ | ||
string fileName = Path.GetFileNameWithoutExtension(file); | ||
|
||
if (LoadedAssemblies.Values.Any(x => Path.GetFileNameWithoutExtension(x.Assembly.Location) == fileName)) | ||
return; | ||
|
||
try | ||
{ | ||
addPlugin(Assembly.LoadFrom(file)); | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Error(e, $"Failed to load plug-in {fileName}"); | ||
} | ||
} | ||
|
||
private void addPlugin(Assembly assembly) | ||
{ | ||
if (LoadedAssemblies.ContainsKey(assembly)) | ||
return; | ||
|
||
if (LoadedAssemblies.Any(x => x.Key.FullName == assembly.FullName)) | ||
return; | ||
|
||
try | ||
{ | ||
LoadedAssemblies[assembly] = assembly.GetTypes().First(x => | ||
x.IsPublic && | ||
x.IsSubclassOf(typeof(Plugin)) && | ||
!x.IsAbstract && | ||
x.GetConstructor(Array.Empty<Type>()) != null | ||
); | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Error(e, $"Failed to add plug-in {assembly}"); | ||
} | ||
} | ||
|
||
private Assembly? resolvePluginDependencyAssembly(object? sender, ResolveEventArgs args) | ||
{ | ||
AssemblyName asm = new(args.Name); | ||
|
||
Assembly? domainAssembly = AppDomain.CurrentDomain.GetAssemblies() | ||
.Where(x => | ||
{ | ||
string? name = x.GetName().Name; | ||
|
||
if (name is null) | ||
return false; | ||
|
||
return args.Name.Contains(name, StringComparison.Ordinal); | ||
}) | ||
.OrderByDescending(x => x.GetName().Version) | ||
.FirstOrDefault(); | ||
|
||
return domainAssembly ?? LoadedAssemblies.Keys.FirstOrDefault(x => x.FullName == asm.FullName); | ||
} | ||
|
||
private void loadUserPlugins(Storage pluginStorage) | ||
{ | ||
IEnumerable<string>? plugins = pluginStorage.GetFiles(".", $"{PLUGIN_LIBRARY_PREFIX}.*.dll"); | ||
|
||
foreach (string? plugin in plugins.Where(x => !x.Contains("Tests"))) | ||
loadPluginFromFile(pluginStorage.GetFullPath(plugin)); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
AppDomain.CurrentDomain.AssemblyResolve -= resolvePluginDependencyAssembly; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace Aurora.Game.API | ||
{ | ||
/// <summary> | ||
/// Indicates the type of plug-in functionality your plug-in holds. | ||
/// </summary> | ||
public enum PluginType | ||
{ | ||
/// <summary> | ||
/// Means that your plug-in introduces a new launcher section (i.e. makes it possible to launch a PvP client). | ||
/// </summary> | ||
LauncherContent, | ||
|
||
/// <summary> | ||
/// Means that your plug-in only gets loaded with the purpose of making tweaks to code or events. | ||
/// </summary> | ||
LauncherModification | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters