Browse Source

Moved all utilities to new location

refactor
Anairkoen Schno 6 years ago
parent
commit
0f7a3cee9d
9 changed files with 24 additions and 603 deletions
  1. +19
    -16
      IPA.Loader/IPA.Loader.csproj
  2. +0
    -97
      IPA.Loader/IllusionInjector/BeatSaber/CompositeBSPlugin.cs
  3. +0
    -77
      IPA.Loader/IllusionInjector/IPA/CompositeIPAPlugin.cs
  4. +0
    -110
      IPA.Loader/IllusionInjector/PluginComponent.cs
  5. +0
    -297
      IPA.Loader/IllusionInjector/PluginManager.cs
  6. +1
    -1
      IPA.Loader/Utilities/Extensions.cs
  7. +1
    -1
      IPA.Loader/Utilities/LoneFunctions.cs
  8. +1
    -1
      IPA.Loader/Utilities/ReflectionUtil.cs
  9. +2
    -3
      IPA.Loader/Utilities/SteamCheck.cs

+ 19
- 16
IPA.Loader/IPA.Loader.csproj View File

@ -51,7 +51,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="IllusionInjector\BeatSaber\CompositeBSPlugin.cs" />
<Compile Include="Loader\Composite\CompositeBSPlugin.cs" />
<Compile Include="PluginInterfaces\BeatSaber\IBeatSaberPlugin.cs" />
<Compile Include="PluginInterfaces\BeatSaber\IEnhancedBeatSaberPlugin.cs" />
<Compile Include="PluginInterfaces\BeatSaber\ModsaberModInfo.cs" />
@ -59,27 +59,27 @@
<Compile Include="IniFile.cs" />
<Compile Include="PluginInterfaces\IPA\IEnhancedPlugin.cs" />
<Compile Include="PluginInterfaces\IPA\IPlugin.cs" />
<Compile Include="IllusionPlugin\Logging\Logger.cs" />
<Compile Include="IllusionPlugin\Logging\LogPrinter.cs" />
<Compile Include="Logging\Logger.cs" />
<Compile Include="Logging\LogPrinter.cs" />
<Compile Include="ModPrefs.cs" />
<Compile Include="IllusionPlugin\Utils\ReflectionUtil.cs" />
<Compile Include="IllusionInjector\IPA\CompositeIPAPlugin.cs" />
<Compile Include="IllusionInjector\Logging\Printers\ColoredConsolePrinter.cs" />
<Compile Include="IllusionInjector\Logging\Printers\GlobalLogFilePrinter.cs" />
<Compile Include="IllusionInjector\Logging\Printers\GZFilePrinter.cs" />
<Compile Include="IllusionInjector\Logging\Printers\PluginLogFilePrinter.cs" />
<Compile Include="IllusionInjector\Logging\StandardLogger.cs" />
<Compile Include="IllusionInjector\Logging\UnityLogInterceptor.cs" />
<Compile Include="IllusionInjector\PluginComponent.cs" />
<Compile Include="IllusionInjector\PluginManager.cs" />
<Compile Include="Utilities\ReflectionUtil.cs" />
<Compile Include="Loader\Composite\CompositeIPAPlugin.cs" />
<Compile Include="Logging\Printers\ColoredConsolePrinter.cs" />
<Compile Include="Logging\Printers\GlobalLogFilePrinter.cs" />
<Compile Include="Logging\Printers\GZFilePrinter.cs" />
<Compile Include="Logging\Printers\PluginLogFilePrinter.cs" />
<Compile Include="Logging\StandardLogger.cs" />
<Compile Include="Logging\UnityLogInterceptor.cs" />
<Compile Include="Loader\PluginComponent.cs" />
<Compile Include="Loader\PluginManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="IllusionInjector\Updating\Backup\BackupUnit.cs" />
<Compile Include="IllusionInjector\Updating\ModsaberML\ApiEndpoint.cs" />
<Compile Include="IllusionInjector\Updating\ModsaberML\Updater.cs" />
<Compile Include="IllusionInjector\Updating\SelfPlugin.cs" />
<Compile Include="IllusionInjector\Utilities\Extensions.cs" />
<Compile Include="IllusionInjector\Utilities\LoneFunctions.cs" />
<Compile Include="IllusionInjector\Utilities\SteamCheck.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\LoneFunctions.cs" />
<Compile Include="Utilities\SteamCheck.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Ionic.Zip">
@ -92,5 +92,8 @@
<Version>11.0.2</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Folder Include="IllusionInjector\Logging\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

+ 0
- 97
IPA.Loader/IllusionInjector/BeatSaber/CompositeBSPlugin.cs View File

@ -1,97 +0,0 @@
using IllusionPlugin;
using IPA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IllusionInjector.Logging.Logger;
namespace IllusionInjector {
public class CompositeBSPlugin : IBeatSaberPlugin
{
IEnumerable<IBeatSaberPlugin> plugins;
private delegate void CompositeCall(IBeatSaberPlugin plugin);
public CompositeBSPlugin(IEnumerable<IBeatSaberPlugin> plugins) {
this.plugins = plugins;
}
public void OnApplicationStart() {
Invoke(plugin => plugin.OnApplicationStart());
}
public void OnApplicationQuit() {
Invoke(plugin => plugin.OnApplicationQuit());
}
public void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode) {
foreach (var plugin in plugins) {
try {
plugin.OnSceneLoaded(scene, sceneMode);
}
catch (Exception ex) {
Logger.log.Error($"{plugin.Name}: {ex}");
}
}
}
public void OnSceneUnloaded(Scene scene) {
foreach (var plugin in plugins) {
try {
plugin.OnSceneUnloaded(scene);
}
catch (Exception ex) {
Logger.log.Error($"{plugin.Name}: {ex}");
}
}
}
public void OnActiveSceneChanged(Scene prevScene, Scene nextScene) {
foreach (var plugin in plugins) {
try {
plugin.OnActiveSceneChanged(prevScene, nextScene);
}
catch (Exception ex) {
Logger.log.Error($"{plugin.Name}: {ex}");
}
}
}
private void Invoke(CompositeCall callback) {
foreach (var plugin in plugins) {
try {
callback(plugin);
}
catch (Exception ex) {
Logger.log.Error($"{plugin.Name}: {ex}");
}
}
}
public void OnUpdate() {
Invoke(plugin => plugin.OnUpdate());
}
public void OnFixedUpdate() {
Invoke(plugin => plugin.OnFixedUpdate());
}
public string Name => throw new NotImplementedException();
public string Version => throw new NotImplementedException();
public Uri UpdateUri => throw new NotImplementedException();
public ModsaberModInfo ModInfo => throw new NotImplementedException();
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedBeatSaberPlugin)
((IEnhancedBeatSaberPlugin) plugin).OnLateUpdate();
});
}
}
}

+ 0
- 77
IPA.Loader/IllusionInjector/IPA/CompositeIPAPlugin.cs View File

@ -1,77 +0,0 @@
using IllusionPlugin;
using System;
using System.Collections.Generic;
using IPA;
using IPA.Old;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IllusionInjector.Logging.Logger;
namespace IllusionInjector {
#pragma warning disable CS0618 // Type or member is obsolete
public class CompositeIPAPlugin : IPlugin
{
IEnumerable<IPlugin> plugins;
private delegate void CompositeCall(IPlugin plugin);
public CompositeIPAPlugin(IEnumerable<IPlugin> plugins) {
this.plugins = plugins;
}
public void OnApplicationStart() {
Invoke(plugin => plugin.OnApplicationStart());
}
public void OnApplicationQuit() {
Invoke(plugin => plugin.OnApplicationQuit());
}
private void Invoke(CompositeCall callback) {
foreach (var plugin in plugins) {
try {
callback(plugin);
}
catch (Exception ex) {
Logger.log.Error($"{plugin.Name}: {ex}");
}
}
}
public void OnUpdate() {
Invoke(plugin => plugin.OnUpdate());
}
public void OnFixedUpdate() {
Invoke(plugin => plugin.OnFixedUpdate());
}
public string Name {
get { throw new NotImplementedException(); }
}
public string Version {
get { throw new NotImplementedException(); }
}
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedBeatSaberPlugin)
((IEnhancedBeatSaberPlugin) plugin).OnLateUpdate();
});
}
public void OnLevelWasLoaded(int level)
{
Invoke(plugin => plugin.OnLevelWasLoaded(level));
}
public void OnLevelWasInitialized(int level)
{
Invoke(plugin => plugin.OnLevelWasInitialized(level));
}
}
#pragma warning restore CS0618 // Type or member is obsolete
}

+ 0
- 110
IPA.Loader/IllusionInjector/PluginComponent.cs View File

@ -1,110 +0,0 @@
using IllusionInjector.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using IPA.Loader;
namespace IllusionInjector
{
public class PluginComponent : MonoBehaviour
{
private CompositeBSPlugin bsPlugins;
private CompositeIPAPlugin ipaPlugins;
private bool quitting = false;
public static PluginComponent Create()
{
Application.logMessageReceived += delegate (string condition, string stackTrace, LogType type)
{
var level = UnityLogInterceptor.LogTypeToLevel(type);
UnityLogInterceptor.Unitylogger.Log(level, $"{condition.Trim()}");
UnityLogInterceptor.Unitylogger.Log(level, $"{stackTrace.Trim()}");
};
return new GameObject("IPA_PluginManager").AddComponent<PluginComponent>();
}
void Awake()
{
DontDestroyOnLoad(gameObject);
bsPlugins = new CompositeBSPlugin(PluginManager.BSPlugins);
ipaPlugins = new CompositeIPAPlugin(PluginManager.Plugins);
// this has no relevance since there is a new mod updater system
//gameObject.AddComponent<ModUpdater>(); // AFTER plugins are loaded, but before most things
gameObject.AddComponent<Updating.ModsaberML.Updater>();
bsPlugins.OnApplicationStart();
ipaPlugins.OnApplicationStart();
SceneManager.activeSceneChanged += OnActiveSceneChanged;
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
void Update()
{
bsPlugins.OnUpdate();
ipaPlugins.OnUpdate();
}
void LateUpdate()
{
bsPlugins.OnLateUpdate();
ipaPlugins.OnLateUpdate();
}
void FixedUpdate()
{
bsPlugins.OnFixedUpdate();
ipaPlugins.OnFixedUpdate();
}
void OnDestroy()
{
if (!quitting)
{
Create();
}
}
void OnApplicationQuit()
{
SceneManager.activeSceneChanged -= OnActiveSceneChanged;
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneUnloaded -= OnSceneUnloaded;
bsPlugins.OnApplicationQuit();
ipaPlugins.OnApplicationQuit();
quitting = true;
}
void OnLevelWasLoaded(int level)
{
ipaPlugins.OnLevelWasLoaded(level);
}
public void OnLevelWasInitialized(int level)
{
ipaPlugins.OnLevelWasInitialized(level);
}
void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode)
{
bsPlugins.OnSceneLoaded(scene, sceneMode);
}
private void OnSceneUnloaded(Scene scene) {
bsPlugins.OnSceneUnloaded(scene);
}
private void OnActiveSceneChanged(Scene prevScene, Scene nextScene) {
bsPlugins.OnActiveSceneChanged(prevScene, nextScene);
}
}
}

+ 0
- 297
IPA.Loader/IllusionInjector/PluginManager.cs View File

@ -1,297 +0,0 @@
using IllusionInjector.Logging;
using IllusionInjector.Updating;
using IllusionInjector.Utilities;
using IllusionPlugin;
using IPA;
using IPA.Old;
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using LoggerBase = IllusionPlugin.Logging.Logger;
namespace IPA.Loader
{
public static class PluginManager
{
#pragma warning disable CS0618 // Type or member is obsolete (IPlugin)
public class BSPluginMeta
{
public IBeatSaberPlugin Plugin { get; internal set; }
public string Filename { get; internal set; }
public ModsaberModInfo ModsaberInfo { get; internal set; }
}
public static IEnumerable<IBeatSaberPlugin> BSPlugins
{
get
{
if(_bsPlugins == null)
{
LoadPlugins();
}
return _bsPlugins.Select(p => p.Plugin);
}
}
private static List<BSPluginMeta> _bsPlugins = null;
internal static IEnumerable<BSPluginMeta> BSMetas
{
get
{
if (_bsPlugins == null)
{
LoadPlugins();
}
return _bsPlugins;
}
}
public static IEnumerable<IPlugin> Plugins
{
get
{
if (_ipaPlugins == null)
{
LoadPlugins();
}
return _ipaPlugins;
}
}
private static List<IPlugin> _ipaPlugins = null;
private static void LoadPlugins()
{
string pluginDirectory = Path.Combine(Environment.CurrentDirectory, "Plugins");
// Process.GetCurrentProcess().MainModule crashes the game and Assembly.GetEntryAssembly() is NULL,
// so we need to resort to P/Invoke
string exeName = Path.GetFileNameWithoutExtension(AppInfo.StartupPath);
Logger.log.Info(exeName);
_bsPlugins = new List<BSPluginMeta>();
_ipaPlugins = new List<IPlugin>();
if (!Directory.Exists(pluginDirectory)) return;
string cacheDir = Path.Combine(pluginDirectory, ".cache");
if (!Directory.Exists(cacheDir))
{
Directory.CreateDirectory(cacheDir);
}
else
{
foreach (string plugin in Directory.GetFiles(cacheDir, "*"))
{
File.Delete(plugin);
}
}
//Copy plugins to .cache
string[] originalPlugins = Directory.GetFiles(pluginDirectory, "*.dll");
foreach (string s in originalPlugins)
{
string pluginCopy = Path.Combine(cacheDir, Path.GetFileName(s));
File.Copy(Path.Combine(pluginDirectory, s), pluginCopy);
}
var selfPlugin = new BSPluginMeta
{
Filename = Path.Combine(Environment.CurrentDirectory, "IPA.exe"),
Plugin = new SelfPlugin()
};
selfPlugin.ModsaberInfo = selfPlugin.Plugin.ModInfo;
_bsPlugins.Add(selfPlugin);
//Load copied plugins
string[] copiedPlugins = Directory.GetFiles(cacheDir, "*.dll");
foreach (string s in copiedPlugins)
{
var result = LoadPluginsFromFile(s, exeName);
_bsPlugins.AddRange(result.Item1);
_ipaPlugins.AddRange(result.Item2);
}
// DEBUG
Logger.log.Info($"Running on Unity {UnityEngine.Application.unityVersion}");
Logger.log.Info($"Game version {UnityEngine.Application.version}");
Logger.log.Info("-----------------------------");
Logger.log.Info($"Loading plugins from {LoneFunctions.GetRelativePath(pluginDirectory, Environment.CurrentDirectory)} and found {_bsPlugins.Count + _ipaPlugins.Count}");
Logger.log.Info("-----------------------------");
foreach (var plugin in _bsPlugins)
{
Logger.log.Info($"{plugin.Plugin.Name}: {plugin.Plugin.Version}");
}
Logger.log.Info("-----------------------------");
foreach (var plugin in _ipaPlugins)
{
Logger.log.Info($"{plugin.Name}: {plugin.Version}");
}
Logger.log.Info("-----------------------------");
}
private static Tuple<IEnumerable<BSPluginMeta>, IEnumerable<IPlugin>> LoadPluginsFromFile(string file, string exeName)
{
List<BSPluginMeta> bsPlugins = new List<BSPluginMeta>();
List<IPlugin> ipaPlugins = new List<IPlugin>();
if (!File.Exists(file) || !file.EndsWith(".dll", true, null))
return new Tuple<IEnumerable<BSPluginMeta>, IEnumerable<IPlugin>>(bsPlugins, ipaPlugins);
T OptionalGetPlugin<T>(Type t) where T : class
{
// use typeof() to allow for easier renaming (in an ideal world this compiles to a string, but ¯\_(ツ)_/¯)
if (t.GetInterface(typeof(T).Name) != null)
{
try
{
T pluginInstance = Activator.CreateInstance(t) as T;
string[] filter = null;
if (pluginInstance is IGenericEnhancedPlugin)
{
filter = ((IGenericEnhancedPlugin)pluginInstance).Filter;
}
if (filter == null || filter.Contains(exeName, StringComparer.OrdinalIgnoreCase))
return pluginInstance;
}
catch (Exception e)
{
Logger.log.Error($"Could not load plugin {t.FullName} in {Path.GetFileName(file)}! {e}");
}
}
return null;
}
try
{
#region Fix assemblies for refactor
var module = ModuleDefinition.ReadModule(file);
bool modifiedModule = false;
foreach (var @ref in module.AssemblyReferences)
{ // fix assembly references
if (@ref.Name == "IllusionPlugin" || @ref.Name == "IllusionInjector")
{
@ref.Name = "IPA.Loader";
modifiedModule = true;
}
}
if (modifiedModule)
{ // types don't need to be fixed if it's already referencing the new version
foreach (var @ref in module.GetTypeReferences())
{ // fix type references
if (@ref.FullName == "IllusionPlugin.IPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.IEnhancedPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = ""
if (@ref.FullName == "IllusionPlugin.IBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = ""
if (@ref.FullName == "IllusionPlugin.IEnhancedBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = ""
if (@ref.FullName == "IllusionPlugin.BeatSaber.ModsaberModInfo") @ref.Namespace = "IPA"; //@ref.Name = ""
if (@ref.FullName == "IllusionPlugin.IniFile") @ref.Namespace = "IPA"; //@ref.Name = ""
if (@ref.FullName == "IllusionPlugin.IModPrefs") @ref.Namespace = "IPA"; //@ref.Name = ""
if (@ref.FullName == "IllusionPlugin.ModPrefs") @ref.Namespace = "IPA"; //@ref.Name = ""
if (@ref.FullName == "IllusionInjector.PluginManager") @ref.Namespace = "IPA.Loader"; //@ref.Name = ""
}
module.Write(file);
}
#endregion
Assembly assembly = Assembly.LoadFrom(file);
foreach (Type t in assembly.GetTypes())
{
IBeatSaberPlugin bsPlugin = OptionalGetPlugin<IBeatSaberPlugin>(t);
if (bsPlugin != null)
{
try
{
var init = t.GetMethod("Init", BindingFlags.Instance | BindingFlags.Public);
if (init != null)
{
var initArgs = new List<object>();
var initParams = init.GetParameters();
LoggerBase modLogger = null;
IModPrefs modPrefs = null;
foreach (var param in initParams)
{
var ptype = param.ParameterType;
if (ptype.IsAssignableFrom(typeof(LoggerBase))) {
if (modLogger == null) modLogger = new StandardLogger(bsPlugin.Name);
initArgs.Add(modLogger);
}
else if (ptype.IsAssignableFrom(typeof(IModPrefs)))
{
if (modPrefs == null) modPrefs = new ModPrefs(bsPlugin);
initArgs.Add(modPrefs);
}
else
initArgs.Add(ptype.GetDefault());
}
init.Invoke(bsPlugin, initArgs.ToArray());
}
bsPlugins.Add(new BSPluginMeta
{
Plugin = bsPlugin,
Filename = file.Replace("\\.cache", ""), // quick and dirty fix
ModsaberInfo = bsPlugin.ModInfo
});
}
catch (AmbiguousMatchException)
{
Logger.log.Error($"Only one Init allowed per plugin");
}
}
else
{
IPlugin ipaPlugin = OptionalGetPlugin<IPlugin>(t);
if (ipaPlugin != null)
{
ipaPlugins.Add(ipaPlugin);
}
}
}
}
catch (Exception e)
{
Logger.log.Error($"Could not load {Path.GetFileName(file)}! {e}");
}
return new Tuple<IEnumerable<BSPluginMeta>, IEnumerable<IPlugin>>(bsPlugins, ipaPlugins);
}
public class AppInfo
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
private static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
public static string StartupPath
{
get
{
StringBuilder stringBuilder = new StringBuilder(260);
GetModuleFileName(NullHandleRef, stringBuilder, stringBuilder.Capacity);
return stringBuilder.ToString();
}
}
}
#pragma warning restore CS0618 // Type or member is obsolete (IPlugin)
}
}

IPA.Loader/IllusionInjector/Utilities/Extensions.cs → IPA.Loader/Utilities/Extensions.cs View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Utilities
namespace IPA.Utilities
{
public static class Extensions
{

IPA.Loader/IllusionInjector/Utilities/LoneFunctions.cs → IPA.Loader/Utilities/LoneFunctions.cs View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Utilities
namespace IPA.Utilities
{
public static class LoneFunctions
{

IPA.Loader/IllusionPlugin/Utils/ReflectionUtil.cs → IPA.Loader/Utilities/ReflectionUtil.cs View File

@ -2,7 +2,7 @@
using System.Reflection;
using UnityEngine;
namespace IllusionPlugin.Utils
namespace IPA.Utilities
{
/// <summary>
/// A utility class providing reflection helper methods.

IPA.Loader/IllusionInjector/Utilities/SteamCheck.cs → IPA.Loader/Utilities/SteamCheck.cs View File

@ -1,11 +1,10 @@
using IllusionInjector.Logging;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Utilities
namespace IPA.Utilities
{
public static class SteamCheck
{

Loading…
Cancel
Save