From ddfc71bdc091203b238971f797cc9b55ae15557b Mon Sep 17 00:00:00 2001 From: Nicolas Gnyra Date: Thu, 14 Mar 2024 06:03:51 -0400 Subject: [PATCH 1/2] Update for Beat Saber 1.35.0 & 1.36.0 --- .../Sabers/Effects/SaberBurnMarkAreaLatch.cs | 25 ----- .../Sabers/Effects/SaberBurnMarkAreaPatch.cs | 93 ++++++++----------- SiraUtil/SiraUtil.csproj | 4 + SiraUtil/Tools/FPFC/FPFCToggle.cs | 2 - SiraUtil/Zenject/Harmony/LateBoundInjector.cs | 9 +- SiraUtil/manifest.json | 4 +- 6 files changed, 47 insertions(+), 90 deletions(-) diff --git a/SiraUtil/Sabers/Effects/SaberBurnMarkAreaLatch.cs b/SiraUtil/Sabers/Effects/SaberBurnMarkAreaLatch.cs index fda6f7b..2da398d 100644 --- a/SiraUtil/Sabers/Effects/SaberBurnMarkAreaLatch.cs +++ b/SiraUtil/Sabers/Effects/SaberBurnMarkAreaLatch.cs @@ -20,13 +20,9 @@ internal class SaberBurnMarkAreaLatch : IDisposable, IAffinity private static readonly FieldAccessor.Accessor PreviousMarks = FieldAccessor.GetAccessor("_prevBurnMarkPos"); private static readonly FieldAccessor.Accessor PreviousMarksValid = FieldAccessor.GetAccessor("_prevBurnMarkPosValid"); private static readonly FieldAccessor.Accessor LinePrefab = FieldAccessor.GetAccessor("_saberBurnMarkLinePrefab"); - private static readonly FieldAccessor.Accessor TextureWidth = FieldAccessor.GetAccessor("_textureWidth"); - private static readonly FieldAccessor.Accessor TextureHeight = FieldAccessor.GetAccessor("_textureHeight"); - private int _lineFactoryIncrement; public SaberBurnMarkAreaLatch(SiraSaberFactory siraSaberFactory, SaberModelManager saberModelManager) { - _lineFactoryIncrement = 2; _siraSaberFactory = siraSaberFactory; _saberModelManager = saberModelManager; _siraSaberFactory.SaberCreated += SiraSaberFactory_SaberCreated; @@ -90,14 +86,6 @@ private LineRenderer CreateNewLineRenderer(Color initialColor) return newLine; } - private RenderTexture CreateNewRenderTexture() - { - RenderTexture renderTexture = new(TextureWidth(ref _saberBurnMarkArea!), TextureHeight(ref _saberBurnMarkArea!), 0, RenderTextureFormat.ARGB32); - renderTexture.name = $"SiraUtil | SaberBurnMarkArea Texture {_lineFactoryIncrement++}"; - renderTexture.hideFlags = HideFlags.DontSave; - return renderTexture; - } - [AffinityPostfix] [AffinityPatch(typeof(SaberBurnMarkArea), nameof(SaberBurnMarkArea.Start))] internal void BurnAreaStarting(SaberBurnMarkArea __instance) @@ -107,18 +95,5 @@ internal void BurnAreaStarting(SaberBurnMarkArea __instance) AddSaber(siraSaber.Saber); _earlySabers.Clear(); } - - [AffinityPostfix] - [AffinityPatch(typeof(SaberBurnMarkArea), nameof(SaberBurnMarkArea.LateUpdate))] - internal void AbsoluteCarouselRenderShift(ref RenderTexture[] ____renderTextures) - { - // Shift every render texture down one in the array - RenderTexture lastTexture = ____renderTextures[____renderTextures.Length - 1]; - for (int i = ____renderTextures.Length - 1; i > 0; i--) - { - ____renderTextures[i] = ____renderTextures[i - 1]; - } - ____renderTextures[0] = lastTexture; - } } } \ No newline at end of file diff --git a/SiraUtil/Sabers/Effects/SaberBurnMarkAreaPatch.cs b/SiraUtil/Sabers/Effects/SaberBurnMarkAreaPatch.cs index d7d35f5..e8e1285 100644 --- a/SiraUtil/Sabers/Effects/SaberBurnMarkAreaPatch.cs +++ b/SiraUtil/Sabers/Effects/SaberBurnMarkAreaPatch.cs @@ -13,17 +13,9 @@ internal class SaberBurnMarkAreaPatch private static readonly MethodInfo _destroyExtraLines = SymbolExtensions.GetMethodInfo(() => DestroyExtraLines(null!)); private static readonly MethodInfo _evaluateAllRenderers = SymbolExtensions.GetMethodInfo(() => CompareAllRenderers(null!)); private static readonly MethodInfo _safeDestroyMethodInfo = SymbolExtensions.GetMethodInfo(() => EssentialHelpers.SafeDestroy(null!)); - private static readonly FieldInfo _lineRendererInfo = typeof(SaberBurnMarkArea).GetField("_lineRenderers", BindingFlags.NonPublic | BindingFlags.Instance); - - private static readonly List _lineCheck = new() - { - OpCodes.Ldarg_0, - OpCodes.Ldfld, - OpCodes.Ldc_I4_0, - OpCodes.Ldelem_Ref, - OpCodes.Callvirt, - OpCodes.Brtrue_S - }; + private static readonly FieldInfo _lineRendererInfo = typeof(SaberBurnMarkArea).GetField(nameof(SaberBurnMarkArea._lineRenderers), BindingFlags.NonPublic | BindingFlags.Instance); + private static readonly FieldInfo _sabersInfo = typeof(SaberBurnMarkArea).GetField(nameof(SaberBurnMarkArea._sabers), BindingFlags.NonPublic | BindingFlags.Instance); + private static readonly MethodInfo _rendererGetEnabled = typeof(Renderer).GetProperty(nameof(Renderer.enabled), BindingFlags.Public | BindingFlags.Instance).GetMethod; [HarmonyPostfix] [HarmonyPatch(nameof(SaberBurnMarkArea.OnEnable))] @@ -47,27 +39,40 @@ internal static void DynamicDisable(ref LineRenderer[] ____lineRenderers) [HarmonyPatch(nameof(SaberBurnMarkArea.LateUpdate))] internal static IEnumerable DynamicUpdate(IEnumerable instructions) { - List codes = instructions.ToList(); - TwoToLength(ref codes); - - bool removedNativeSwap = false; - for (int i = codes.Count - 1; i >= 0; i--) - { - if (removedNativeSwap && codes[i].Is(OpCodes.Ldfld, _lineRendererInfo)) - { - codes.RemoveAt(i + 1); - codes.RemoveAt(i + 1); - codes[i + 1] = new CodeInstruction(OpCodes.Callvirt, _evaluateAllRenderers); - break; - } - if (!removedNativeSwap && codes[i].opcode == OpCodes.Call) - { - codes.RemoveRange(i + 1, codes.Count - i - 1); - codes.Add(new(OpCodes.Ret)); - removedNativeSwap = true; - } - } - return codes; + return new CodeMatcher(instructions) + // replace hardcoded 2 in `for (int i = 0; i < 2; i++)` with length of _sabers array + .MatchForward( + false, + new CodeMatch(OpCodes.Ldc_I4_2), + new CodeMatch(OpCodes.Blt)) + .ThrowIfInvalid("Ldc_I4_2 not found") + .RemoveInstruction() + .InsertAndAdvance( + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldfld, _sabersInfo), + new CodeInstruction(OpCodes.Ldlen), + new CodeInstruction(OpCodes.Conv_I4)) + // remove hardcoded check of _lineRenderers at index 0 and 1 with check on everything in the array + // `if (_lineRenderers[0].enabled || _lineRenderers[1].enabled)` + .MatchForward( + false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(i => i.LoadsField(_lineRendererInfo)), + new CodeMatch(OpCodes.Ldc_I4_0), + new CodeMatch(OpCodes.Ldelem_Ref), + new CodeMatch(i => i.Calls(_rendererGetEnabled)), + new CodeMatch(OpCodes.Brtrue), + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(i => i.LoadsField(_lineRendererInfo)), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(OpCodes.Ldelem_Ref), + new CodeMatch(i => i.Calls(_rendererGetEnabled)), + new CodeMatch(OpCodes.Brfalse)) + .ThrowIfInvalid("_lineRenderers comparison not found") + .Advance(2) // keep _lineRenderers field load + .RemoveInstructions(9) // remove everything until the final brfalse + .InsertAndAdvance(new CodeInstruction(OpCodes.Call, _evaluateAllRenderers)) + .InstructionEnumeration(); } // This destroys the other line renderers in between where the first ones were destroyed and when the fade out material is destroyed. @@ -119,29 +124,5 @@ private static void DestroyExtraLines(LineRenderer[] lineRenderers) if (lineRenderers[i] != null) Object.Destroy(lineRenderers[i]); } - - private static void TwoToLength(ref List codes) - { - object? array = null; - - for (int i = 0; i < codes.Count; i++) - { - if (codes[i].opcode == OpCodes.Ldfld && array is null) // We collect the operand that we are going to be using _sabers - array = codes[i].operand; - - if (codes[i].opcode == OpCodes.Ldc_I4_2) - { - codes.RemoveAt(i); // Remove the '2' being pushed onto the stack - codes.InsertRange(i, new CodeInstruction[] // And use the Length property of the array - { - new CodeInstruction(OpCodes.Ldarg_0), - new CodeInstruction(OpCodes.Ldfld, array), // this needs operand of _sabers - new CodeInstruction(OpCodes.Ldlen), - new CodeInstruction(OpCodes.Conv_I4) - }); - break; - } - } - } } } \ No newline at end of file diff --git a/SiraUtil/SiraUtil.csproj b/SiraUtil/SiraUtil.csproj index 5e07a2b..51a9c2b 100644 --- a/SiraUtil/SiraUtil.csproj +++ b/SiraUtil/SiraUtil.csproj @@ -54,6 +54,10 @@ $(BeatSaberDir)\Libs\0Harmony.dll + + $(BeatSaberDir)\Beat Saber_Data\Managed\BeatSaber.Init.dll + False + $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.AppFlow.dll True diff --git a/SiraUtil/Tools/FPFC/FPFCToggle.cs b/SiraUtil/Tools/FPFC/FPFCToggle.cs index 7e1114d..4ddc463 100644 --- a/SiraUtil/Tools/FPFC/FPFCToggle.cs +++ b/SiraUtil/Tools/FPFC/FPFCToggle.cs @@ -186,8 +186,6 @@ private void DisableFPFC() public void Dispose() { _fpfcSettings.Changed -= FPFCSettings_Changed; - - InitializeXRLoader(); } public void Tick() diff --git a/SiraUtil/Zenject/Harmony/LateBoundInjector.cs b/SiraUtil/Zenject/Harmony/LateBoundInjector.cs index 7229639..a149a50 100644 --- a/SiraUtil/Zenject/Harmony/LateBoundInjector.cs +++ b/SiraUtil/Zenject/Harmony/LateBoundInjector.cs @@ -1,5 +1,4 @@ using HarmonyLib; -using IPA.Utilities; using System; using UnityEngine; using UnityEngine.SceneManagement; @@ -13,7 +12,7 @@ internal class LateBoundInjector private static SiraPCScenesTransitionSetupDataSO _restartTransitionData = null!; [HarmonyPrefix] - public static bool Prefix(GameScenesManager __instance, ScenesTransitionSetupDataSO scenesTransitionSetupData) + public static bool Prefix(GameScenesManager __instance) { if (!ZenjectManager.InitialSceneConstructionRegistered) { @@ -23,8 +22,8 @@ public static bool Prefix(GameScenesManager __instance, ScenesTransitionSetupDat } __instance.ClearAndOpenScenes(_restartTransitionData, finishCallback: (_) => { - PCAppInit pcAppInit = SceneManager.GetSceneByName(__instance.GetCurrentlyLoadedSceneNames()[0]).GetRootGameObjects()[0].GetComponent(); - pcAppInit.InvokeMethod("TransitionToNextScene"); + PCAppInit pcAppInit = SceneManager.GetSceneByName(_initialSceneName).GetRootGameObjects()[0].GetComponent(); + pcAppInit.TransitionToNextScene(); }); return false; } @@ -36,7 +35,7 @@ internal class SiraPCScenesTransitionSetupDataSO : ScenesTransitionSetupDataSO protected override void OnEnable() { var si = CreateInstance(); - si.SetField("_sceneName", _initialSceneName); + si._sceneName = _initialSceneName; Init(new SceneInfo[] { si }, Array.Empty()); base.OnEnable(); } diff --git a/SiraUtil/manifest.json b/SiraUtil/manifest.json index 46a2010..8cf428f 100644 --- a/SiraUtil/manifest.json +++ b/SiraUtil/manifest.json @@ -3,10 +3,10 @@ "id": "SiraUtil", "name": "SiraUtil", "author": "Auros", - "version": "3.1.7", + "version": "3.1.8", "icon": "SiraUtil.Resources.logo.png", "description": "A powerful utility mod which provides more tools to Beat Saber modders.", - "gameVersion": "1.34.5", + "gameVersion": "1.35.0", "dependsOn": { "BSIPA": "^4.3.0" }, From 08531687b55d2da8920e21f96587d8cd8ab9ebc7 Mon Sep 17 00:00:00 2001 From: Nicolas Gnyra Date: Thu, 23 May 2024 19:19:42 -0400 Subject: [PATCH 2/2] Fix tracking not working after internal restart while FPFC is enabled --- SiraUtil/Tools/FPFC/FPFCSettingsController.cs | 48 ++++++++++++++++++- SiraUtil/Tools/FPFC/FPFCToggle.cs | 37 -------------- SiraUtil/manifest.json | 2 +- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/SiraUtil/Tools/FPFC/FPFCSettingsController.cs b/SiraUtil/Tools/FPFC/FPFCSettingsController.cs index 067785f..f88f2f2 100644 --- a/SiraUtil/Tools/FPFC/FPFCSettingsController.cs +++ b/SiraUtil/Tools/FPFC/FPFCSettingsController.cs @@ -1,5 +1,8 @@ -using System; +using SiraUtil.Logging; +using System; +using System.Linq; using UnityEngine; +using UnityEngine.XR.Management; using Zenject; namespace SiraUtil.Tools.FPFC @@ -18,6 +21,12 @@ public bool Enabled set { _enabled = value; + + if (value) + DeinitializeXRLoader(); + else + InitializeXRLoader(); + Changed?.Invoke(this); } } @@ -26,10 +35,12 @@ public bool Enabled public event Action? Changed; private readonly FPFCOptions _fpfcOptions; + private readonly SiraLog _siraLog; - public FPFCSettingsController(FPFCOptions fpfcOptions) + public FPFCSettingsController(FPFCOptions fpfcOptions, SiraLog siraLog) { _fpfcOptions = fpfcOptions; + _siraLog = siraLog; Enabled = !_fpfcOptions.Ignore; } @@ -45,6 +56,7 @@ public void Tick() public void Initialize() { _fpfcOptions.Updated += ConfigUpdated; + DeinitializeXRLoader(); } private void ConfigUpdated(FPFCOptions _) @@ -55,6 +67,38 @@ private void ConfigUpdated(FPFCOptions _) public void Dispose() { _fpfcOptions.Updated -= ConfigUpdated; + InitializeXRLoader(); + } + + // we unfortunately need to fully deinitialize/initialize the XR loader since OpenXR doesn't simply stop/start properly + private void InitializeXRLoader() + { + XRManagerSettings manager = XRGeneralSettings.Instance.Manager; + + if (manager.activeLoader != null || !manager.activeLoaders.Any(l => l != null)) + return; + + _siraLog.Notice("Enabling XR Loader"); + manager.InitializeLoaderSync(); + + if (!manager.isInitializationComplete) + { + _siraLog.Error("Failed to initialize XR loader"); + return; + } + + manager.StartSubsystems(); + } + + private void DeinitializeXRLoader() + { + XRManagerSettings manager = XRGeneralSettings.Instance.Manager; + + if (manager.activeLoader == null) + return; + + _siraLog.Notice("Disabling XR Loader"); + manager.DeinitializeLoader(); } } } \ No newline at end of file diff --git a/SiraUtil/Tools/FPFC/FPFCToggle.cs b/SiraUtil/Tools/FPFC/FPFCToggle.cs index 4ddc463..1558d6a 100644 --- a/SiraUtil/Tools/FPFC/FPFCToggle.cs +++ b/SiraUtil/Tools/FPFC/FPFCToggle.cs @@ -3,13 +3,11 @@ using SiraUtil.Zenject; using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SpatialTracking; -using UnityEngine.XR.Management; using VRUIControls; using Zenject; @@ -135,8 +133,6 @@ private void EnableFPFC() foreach (var listener in _fpfcListeners) listener.Enabled(); - - DeinitializeXRLoader(); } private void DisableFPFC() @@ -179,8 +175,6 @@ private void DisableFPFC() foreach (var listener in _fpfcListeners) listener.Disabled(); - - InitializeXRLoader(); } public void Dispose() @@ -197,36 +191,5 @@ public void Tick() Cursor.visible = false; } } - - // we unfortunately need to fully deinitialize/initialize the XR loader since OpenXR doesn't simply stop/start properly - private void InitializeXRLoader() - { - XRManagerSettings manager = XRGeneralSettings.Instance.Manager; - - if (manager.activeLoader != null || !manager.activeLoaders.Any(l => l != null)) - return; - - _siraLog.Notice("Enabling XR Loader"); - manager.InitializeLoaderSync(); - - if (!manager.isInitializationComplete) - { - _siraLog.Error("Failed to initialize XR loader"); - return; - } - - manager.StartSubsystems(); - } - - private void DeinitializeXRLoader() - { - XRManagerSettings manager = XRGeneralSettings.Instance.Manager; - - if (manager.activeLoader == null) - return; - - _siraLog.Notice("Disabling XR Loader"); - manager.DeinitializeLoader(); - } } } \ No newline at end of file diff --git a/SiraUtil/manifest.json b/SiraUtil/manifest.json index 8cf428f..5548a20 100644 --- a/SiraUtil/manifest.json +++ b/SiraUtil/manifest.json @@ -3,7 +3,7 @@ "id": "SiraUtil", "name": "SiraUtil", "author": "Auros", - "version": "3.1.8", + "version": "3.1.9", "icon": "SiraUtil.Resources.logo.png", "description": "A powerful utility mod which provides more tools to Beat Saber modders.", "gameVersion": "1.35.0",