diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj index daae1d20..49b51c87 100644 --- a/IPA.Loader/IPA.Loader.csproj +++ b/IPA.Loader/IPA.Loader.csproj @@ -51,7 +51,7 @@ - + @@ -59,27 +59,27 @@ - - + + - - - - - - - - - - + + + + + + + + + + - - - + + + @@ -92,5 +92,8 @@ 11.0.2 + + + \ No newline at end of file diff --git a/IPA.Loader/IllusionInjector/BeatSaber/CompositeBSPlugin.cs b/IPA.Loader/IllusionInjector/BeatSaber/CompositeBSPlugin.cs deleted file mode 100644 index acff0c2e..00000000 --- a/IPA.Loader/IllusionInjector/BeatSaber/CompositeBSPlugin.cs +++ /dev/null @@ -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 plugins; - - private delegate void CompositeCall(IBeatSaberPlugin plugin); - - public CompositeBSPlugin(IEnumerable 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(); - }); - } - } -} \ No newline at end of file diff --git a/IPA.Loader/IllusionInjector/IPA/CompositeIPAPlugin.cs b/IPA.Loader/IllusionInjector/IPA/CompositeIPAPlugin.cs deleted file mode 100644 index f66b73a0..00000000 --- a/IPA.Loader/IllusionInjector/IPA/CompositeIPAPlugin.cs +++ /dev/null @@ -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 plugins; - - private delegate void CompositeCall(IPlugin plugin); - - public CompositeIPAPlugin(IEnumerable 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 -} \ No newline at end of file diff --git a/IPA.Loader/IllusionInjector/PluginComponent.cs b/IPA.Loader/IllusionInjector/PluginComponent.cs deleted file mode 100644 index 86206cce..00000000 --- a/IPA.Loader/IllusionInjector/PluginComponent.cs +++ /dev/null @@ -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(); - } - - 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(); // AFTER plugins are loaded, but before most things - gameObject.AddComponent(); - - 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); - } - - } -} diff --git a/IPA.Loader/IllusionInjector/PluginManager.cs b/IPA.Loader/IllusionInjector/PluginManager.cs deleted file mode 100644 index 4db9473e..00000000 --- a/IPA.Loader/IllusionInjector/PluginManager.cs +++ /dev/null @@ -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 BSPlugins - { - get - { - if(_bsPlugins == null) - { - LoadPlugins(); - } - return _bsPlugins.Select(p => p.Plugin); - } - } - private static List _bsPlugins = null; - internal static IEnumerable BSMetas - { - get - { - if (_bsPlugins == null) - { - LoadPlugins(); - } - return _bsPlugins; - } - } - - public static IEnumerable Plugins - { - get - { - if (_ipaPlugins == null) - { - LoadPlugins(); - } - return _ipaPlugins; - } - } - private static List _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(); - _ipaPlugins = new List(); - - 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> LoadPluginsFromFile(string file, string exeName) - { - List bsPlugins = new List(); - List ipaPlugins = new List(); - - if (!File.Exists(file) || !file.EndsWith(".dll", true, null)) - return new Tuple, IEnumerable>(bsPlugins, ipaPlugins); - - T OptionalGetPlugin(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(t); - if (bsPlugin != null) - { - try - { - var init = t.GetMethod("Init", BindingFlags.Instance | BindingFlags.Public); - if (init != null) - { - var initArgs = new List(); - 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(t); - if (ipaPlugin != null) - { - ipaPlugins.Add(ipaPlugin); - } - } - } - - } - catch (Exception e) - { - Logger.log.Error($"Could not load {Path.GetFileName(file)}! {e}"); - } - - return new Tuple, IEnumerable>(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) - } -} diff --git a/IPA.Loader/IllusionInjector/Utilities/Extensions.cs b/IPA.Loader/Utilities/Extensions.cs similarity index 91% rename from IPA.Loader/IllusionInjector/Utilities/Extensions.cs rename to IPA.Loader/Utilities/Extensions.cs index 326c675a..7a1c3399 100644 --- a/IPA.Loader/IllusionInjector/Utilities/Extensions.cs +++ b/IPA.Loader/Utilities/Extensions.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace IllusionInjector.Utilities +namespace IPA.Utilities { public static class Extensions { diff --git a/IPA.Loader/IllusionInjector/Utilities/LoneFunctions.cs b/IPA.Loader/Utilities/LoneFunctions.cs similarity index 98% rename from IPA.Loader/IllusionInjector/Utilities/LoneFunctions.cs rename to IPA.Loader/Utilities/LoneFunctions.cs index c270f6e8..1ed0b4db 100644 --- a/IPA.Loader/IllusionInjector/Utilities/LoneFunctions.cs +++ b/IPA.Loader/Utilities/LoneFunctions.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace IllusionInjector.Utilities +namespace IPA.Utilities { public static class LoneFunctions { diff --git a/IPA.Loader/IllusionPlugin/Utils/ReflectionUtil.cs b/IPA.Loader/Utilities/ReflectionUtil.cs similarity index 99% rename from IPA.Loader/IllusionPlugin/Utils/ReflectionUtil.cs rename to IPA.Loader/Utilities/ReflectionUtil.cs index cf8fdde1..5a716359 100644 --- a/IPA.Loader/IllusionPlugin/Utils/ReflectionUtil.cs +++ b/IPA.Loader/Utilities/ReflectionUtil.cs @@ -2,7 +2,7 @@ using System.Reflection; using UnityEngine; -namespace IllusionPlugin.Utils +namespace IPA.Utilities { /// /// A utility class providing reflection helper methods. diff --git a/IPA.Loader/IllusionInjector/Utilities/SteamCheck.cs b/IPA.Loader/Utilities/SteamCheck.cs similarity index 92% rename from IPA.Loader/IllusionInjector/Utilities/SteamCheck.cs rename to IPA.Loader/Utilities/SteamCheck.cs index a4f9624b..08bb004e 100644 --- a/IPA.Loader/IllusionInjector/Utilities/SteamCheck.cs +++ b/IPA.Loader/Utilities/SteamCheck.cs @@ -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 {