diff --git a/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs b/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs index 0c7930f0..696c1a66 100644 --- a/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs +++ b/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs @@ -171,7 +171,6 @@ namespace BSIPA_ModList.UI { private TextMeshProUGUI titleText; private TextMeshProUGUI authorText; - private TextMeshProUGUI descText; private Image icon; public void Init(ModInfoViewController controller) diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs index cef45ff4..7c167cac 100644 --- a/IPA.Injector/Injector.cs +++ b/IPA.Injector/Injector.cs @@ -183,8 +183,8 @@ namespace IPA.Injector bkp?.Add(unityPath); unityAsmDef.Write(unityPath); } - else - return; // shortcut + /*else + return; // shortcut*/ } #endregion Insert patch into UnityEngine.CoreModule.dll @@ -206,7 +206,8 @@ namespace IPA.Injector #region Anti-Yeet - if (SelfConfig.SelfConfigRef.Value.ApplyAntiYeet) + //if (SelfConfig.SelfConfigRef.Value.ApplyAntiYeet) + try { loader.Debug("Applying anti-yeet patch"); @@ -223,6 +224,10 @@ namespace IPA.Injector ascAsmDef.Write(ascPath); } + catch (Exception) + { + // ignore + } #endregion } diff --git a/IPA.Loader/Config/SelfConfig.cs b/IPA.Loader/Config/SelfConfig.cs index cb3e6e39..07a4711d 100644 --- a/IPA.Loader/Config/SelfConfig.cs +++ b/IPA.Loader/Config/SelfConfig.cs @@ -1,5 +1,9 @@ -using IPA.Logging; +using IPA.JsonConverters; +using IPA.Logging; using IPA.Utilities; +using Newtonsoft.Json; +using SemVer; +using System; namespace IPA.Config { @@ -33,10 +37,11 @@ namespace IPA.Config } internal const string IPAName = "Beat Saber IPA"; - internal const string IPAVersion = "3.12.17"; + internal const string IPAVersion = "3.12.18"; public bool Regenerate = true; + [Obsolete("No longer does anything, built-in mod yeeter always disabled")] public bool ApplyAntiYeet = false; public class UpdateObject @@ -57,5 +62,7 @@ namespace IPA.Config } public DebugObject Debug = new DebugObject(); + + public string LastGameVersion = null; } } \ No newline at end of file diff --git a/IPA.Loader/JsonConverters/SemverVersionConverter.cs b/IPA.Loader/JsonConverters/SemverVersionConverter.cs index 50e13791..c79d2959 100644 --- a/IPA.Loader/JsonConverters/SemverVersionConverter.cs +++ b/IPA.Loader/JsonConverters/SemverVersionConverter.cs @@ -6,8 +6,12 @@ namespace IPA.JsonConverters { internal class SemverVersionConverter : JsonConverter { - public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer) => new Version(reader.Value as string, true); + public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer) => reader.Value == null ? null : new Version(reader.Value as string, true); - public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer) => writer.WriteValue(value.ToString()); + public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer) + { + if (value == null) writer.WriteNull(); + else writer.WriteValue(value.ToString()); + } } } diff --git a/IPA.Loader/Loader/Composite/CompositeBSPlugin.cs b/IPA.Loader/Loader/Composite/CompositeBSPlugin.cs index 797ac2b1..d4e9c755 100644 --- a/IPA.Loader/Loader/Composite/CompositeBSPlugin.cs +++ b/IPA.Loader/Loader/Composite/CompositeBSPlugin.cs @@ -59,8 +59,6 @@ namespace IPA.Loader.Composite public string Version => throw new InvalidOperationException(); - public ModsaberModInfo ModInfo => throw new InvalidOperationException(); - public void OnLateUpdate() { Invoke(plugin => { if (plugin.Plugin is IEnhancedBeatSaberPlugin saberPlugin) diff --git a/IPA.Loader/Loader/Features/Feature.cs b/IPA.Loader/Loader/Features/Feature.cs index 4b103b1b..572ed672 100644 --- a/IPA.Loader/Loader/Features/Feature.cs +++ b/IPA.Loader/Loader/Features/Feature.cs @@ -74,10 +74,20 @@ namespace IPA.Loader.Features /// protected internal virtual bool StoreOnPlugin => true; - private static readonly Dictionary featureTypes = new Dictionary + static Feature() { - { "define-feature", typeof(DefineFeature) } - }; + Reset(); + } + + internal static void Reset() + { + featureTypes = new Dictionary + { + { "define-feature", typeof(DefineFeature) } + }; + } + + private static Dictionary featureTypes; internal static bool HasFeature(string name) => featureTypes.ContainsKey(name); diff --git a/IPA.Loader/Loader/PluginComponent.cs b/IPA.Loader/Loader/PluginComponent.cs index f25f29db..fab8830c 100644 --- a/IPA.Loader/Loader/PluginComponent.cs +++ b/IPA.Loader/Loader/PluginComponent.cs @@ -23,6 +23,8 @@ namespace IPA.Loader { DontDestroyOnLoad(gameObject); + PluginManager.Load(); + bsPlugins = new CompositeBSPlugin(PluginManager.BSMetas); #pragma warning disable 618 ipaPlugins = new CompositeIPAPlugin(PluginManager.Plugins); diff --git a/IPA.Loader/Loader/PluginLoader.cs b/IPA.Loader/Loader/PluginLoader.cs index 762fb6d6..6f439a8c 100644 --- a/IPA.Loader/Loader/PluginLoader.cs +++ b/IPA.Loader/Loader/PluginLoader.cs @@ -24,7 +24,6 @@ namespace IPA.Loader LoadMetadata(); Resolve(); ComputeLoadOrder(); - InitFeatures(); }); /// @@ -109,7 +108,7 @@ namespace IPA.Loader internal static List PluginsMetadata = new List(); - private static Regex embeddedTextDescriptionPattern = new Regex(@"#!\[(.+)\]", RegexOptions.Compiled | RegexOptions.Singleline); + private static readonly Regex embeddedTextDescriptionPattern = new Regex(@"#!\[(.+)\]", RegexOptions.Compiled | RegexOptions.Singleline); internal static void LoadMetadata() { @@ -502,6 +501,14 @@ namespace IPA.Loader } } + internal static void ReleaseAll() + { + ignoredPlugins = new HashSet(); + PluginsMetadata = new List(); + Feature.Reset(); + GC.Collect(); + } + internal static void Load(PluginMetadata meta) { if (meta.Assembly == null && meta.PluginType != null) @@ -519,6 +526,9 @@ namespace IPA.Loader var info = new PluginInfo(); + if (meta.Manifest.GameVersion != BeatSaber.GameVersion) + Logger.loader.Warn($"Mod {meta.Name} developed for game version {meta.Manifest.GameVersion}, so it may not work properly."); + try { Load(meta); @@ -580,6 +590,10 @@ namespace IPA.Loader return info; } - internal static List LoadPlugins() => PluginsMetadata.Select(InitPlugin).Where(p => p != null).ToList(); + internal static List LoadPlugins() + { + InitFeatures(); + return PluginsMetadata.Select(InitPlugin).Where(p => p != null).ToList(); + } } } \ No newline at end of file diff --git a/IPA.Loader/Loader/PluginManager.cs b/IPA.Loader/Loader/PluginManager.cs index f69f49c2..fdaee05f 100644 --- a/IPA.Loader/Loader/PluginManager.cs +++ b/IPA.Loader/Loader/PluginManager.cs @@ -37,18 +37,9 @@ namespace IPA.Loader return (_bsPlugins ?? throw new InvalidOperationException()).Select(p => p.Plugin); } } + private static List _bsPlugins; - internal static IEnumerable BSMetas - { - get - { - if (_bsPlugins == null) - { - LoadPlugins(); - } - return _bsPlugins; - } - } + internal static IEnumerable BSMetas => _bsPlugins; /// /// Gets info about the plugin with the specified name. @@ -76,27 +67,48 @@ namespace IPA.Loader public static IEnumerable AllPlugins => BSMetas; /// - /// An of old IPA plugins + /// An of old IPA plugins. /// [Obsolete("I mean, IPlugin shouldn't be used, so why should this? Not renaming to extend support for old plugins.")] - public static IEnumerable Plugins + public static IEnumerable Plugins => _ipaPlugins; + private static List _ipaPlugins; + + internal static IConfigProvider SelfConfigProvider { get; set; } + + internal static void Load() { - get + string pluginDir = BeatSaber.PluginsPath; + var gameVer = BeatSaber.GameVersion; + var lastVerS = SelfConfig.SelfConfigRef.Value.LastGameVersion; + var lastVer = lastVerS != null ? new SemVer.Version(lastVerS) : null; + + if (lastVer != null && gameVer != lastVer) { - if (_ipaPlugins == null) - { - LoadPlugins(); - } - return _ipaPlugins; + var oldPluginsName = Path.Combine(BeatSaber.InstallPath, $"{lastVer} Plugins"); + var newPluginsName = Path.Combine(BeatSaber.InstallPath, $"{gameVer} Plugins"); + + ReleaseAll(); + + if (Directory.Exists(oldPluginsName)) + Directory.Delete(oldPluginsName, true); + Directory.Move(pluginDir, oldPluginsName); + if (Directory.Exists(newPluginsName)) + Directory.Move(newPluginsName, pluginDir); + else + Directory.CreateDirectory(pluginDir); + + LoadTask().Wait(); } - } - private static List _ipaPlugins; - internal static IConfigProvider SelfConfigProvider { get; set; } + SelfConfig.SelfConfigRef.Value.LastGameVersion = gameVer.ToString(); + SelfConfig.LoaderConfig.Store(SelfConfig.SelfConfigRef.Value); + + LoadPlugins(); + } private static void LoadPlugins() { - string pluginDirectory = Path.Combine(Environment.CurrentDirectory, "Plugins"); + string pluginDirectory = BeatSaber.PluginsPath; // Process.GetCurrentProcess().MainModule crashes the game and Assembly.GetEntryAssembly() is NULL, // so we need to resort to P/Invoke diff --git a/IPA.Loader/Loader/manifest.json b/IPA.Loader/Loader/manifest.json index 7e9f8137..b6e0d985 100644 --- a/IPA.Loader/Loader/manifest.json +++ b/IPA.Loader/Loader/manifest.json @@ -8,7 +8,7 @@ "gameVersion": "0.13.2", "id": "BSIPA", "name": "Beat Saber IPA", - "version": "3.12.17", + "version": "3.12.18", "icon": "IPA.icon.png", "features": [ "define-feature(print, IPA.Loader.Features.PrintFeature)", diff --git a/IPA/Program.cs b/IPA/Program.cs index 46f95139..7a1e20b5 100644 --- a/IPA/Program.cs +++ b/IPA/Program.cs @@ -23,7 +23,7 @@ namespace IPA Unknown } - public const string FileVersion = "3.12.17"; + public const string FileVersion = "3.12.18"; public static Version Version => Assembly.GetEntryAssembly().GetName().Version; diff --git a/Refs/BeatSaberCustomUI.dll b/Refs/BeatSaberCustomUI.dll index f1ee3f67..41662300 100644 Binary files a/Refs/BeatSaberCustomUI.dll and b/Refs/BeatSaberCustomUI.dll differ diff --git a/Refs/BeatSaberCustomUI.xml b/Refs/BeatSaberCustomUI.xml index 5fbaa627..9ad1b55a 100644 --- a/Refs/BeatSaberCustomUI.xml +++ b/Refs/BeatSaberCustomUI.xml @@ -129,6 +129,28 @@ The size of the color picker's RectTransform. + + + Creates a custom TextSegmentedControl component. + + Thet transform to parent the new TextSegmentedControl component to. + The position the TextSegmentedControl component should be anchored to. + The size of the TextSegmentedControl component RectTransform. + Callback when the user clicks on one of the segments. + Size of text in segments. + Size of padding in segments. + The newly created TextSegmentedControl component. + + + + Creates a custom IconSegmentedControl component. + + Thet transform to parent the new IconSegmentedControl component to. + The position the IconSegmentedControl component should be anchored to. + The size of the IconSegmentedControl component RectTransform. + Callback when the user clicks on one of the segments. + The newly created IconSegmentedControl component. + The FlowCoordinator that presented this FlowCoordinator diff --git a/Refs/Unity.TextMeshPro.dll b/Refs/Unity.TextMeshPro.dll index 56123d46..244bc8fd 100644 Binary files a/Refs/Unity.TextMeshPro.dll and b/Refs/Unity.TextMeshPro.dll differ diff --git a/Refs/UnityEngine.CoreModule.dll b/Refs/UnityEngine.CoreModule.dll index df98f54c..18fac61d 100644 Binary files a/Refs/UnityEngine.CoreModule.dll and b/Refs/UnityEngine.CoreModule.dll differ diff --git a/appveyor.yml b/appveyor.yml index 0f8aef76..bb967aa2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: 'BSIPA-{branch}-{build}' environment: - bsipa_version: '3.12.17' + bsipa_version: '3.12.18' pull_requests: do_not_increment_build_number: true install: