Skip to content

Commit

Permalink
Merge pull request #68 from nicoco007/beat-saber-1.36.0
Browse files Browse the repository at this point in the history
Update for Beat Saber 1.35.0 & 1.36.0
  • Loading branch information
Auros authored Jun 4, 2024
2 parents 7c40f99 + 0853168 commit 52eb38d
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 129 deletions.
25 changes: 0 additions & 25 deletions SiraUtil/Sabers/Effects/SaberBurnMarkAreaLatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@ internal class SaberBurnMarkAreaLatch : IDisposable, IAffinity
private static readonly FieldAccessor<SaberBurnMarkArea, Vector3[]>.Accessor PreviousMarks = FieldAccessor<SaberBurnMarkArea, Vector3[]>.GetAccessor("_prevBurnMarkPos");
private static readonly FieldAccessor<SaberBurnMarkArea, bool[]>.Accessor PreviousMarksValid = FieldAccessor<SaberBurnMarkArea, bool[]>.GetAccessor("_prevBurnMarkPosValid");
private static readonly FieldAccessor<SaberBurnMarkArea, LineRenderer>.Accessor LinePrefab = FieldAccessor<SaberBurnMarkArea, LineRenderer>.GetAccessor("_saberBurnMarkLinePrefab");
private static readonly FieldAccessor<SaberBurnMarkArea, int>.Accessor TextureWidth = FieldAccessor<SaberBurnMarkArea, int>.GetAccessor("_textureWidth");
private static readonly FieldAccessor<SaberBurnMarkArea, int>.Accessor TextureHeight = FieldAccessor<SaberBurnMarkArea, int>.GetAccessor("_textureHeight");
private int _lineFactoryIncrement;

public SaberBurnMarkAreaLatch(SiraSaberFactory siraSaberFactory, SaberModelManager saberModelManager)
{
_lineFactoryIncrement = 2;
_siraSaberFactory = siraSaberFactory;
_saberModelManager = saberModelManager;
_siraSaberFactory.SaberCreated += SiraSaberFactory_SaberCreated;
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}
}
}
93 changes: 37 additions & 56 deletions SiraUtil/Sabers/Effects/SaberBurnMarkAreaPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<OpCode> _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))]
Expand All @@ -47,27 +39,40 @@ internal static void DynamicDisable(ref LineRenderer[] ____lineRenderers)
[HarmonyPatch(nameof(SaberBurnMarkArea.LateUpdate))]
internal static IEnumerable<CodeInstruction> DynamicUpdate(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> 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.
Expand Down Expand Up @@ -119,29 +124,5 @@ private static void DestroyExtraLines(LineRenderer[] lineRenderers)
if (lineRenderers[i] != null)
Object.Destroy(lineRenderers[i]);
}

private static void TwoToLength(ref List<CodeInstruction> 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;
}
}
}
}
}
4 changes: 4 additions & 0 deletions SiraUtil/SiraUtil.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<Reference Include="0Harmony">
<HintPath>$(BeatSaberDir)\Libs\0Harmony.dll</HintPath>
</Reference>
<Reference Include="BeatSaber.Init">
<HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\BeatSaber.Init.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BGLib.AppFlow">
<HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.AppFlow.dll</HintPath>
<Publicize>True</Publicize>
Expand Down
48 changes: 46 additions & 2 deletions SiraUtil/Tools/FPFC/FPFCSettingsController.cs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,6 +21,12 @@ public bool Enabled
set
{
_enabled = value;

if (value)
DeinitializeXRLoader();
else
InitializeXRLoader();

Changed?.Invoke(this);
}
}
Expand All @@ -26,10 +35,12 @@ public bool Enabled

public event Action<IFPFCSettings>? 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;
}

Expand All @@ -45,6 +56,7 @@ public void Tick()
public void Initialize()
{
_fpfcOptions.Updated += ConfigUpdated;
DeinitializeXRLoader();
}

private void ConfigUpdated(FPFCOptions _)
Expand All @@ -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();
}
}
}
39 changes: 0 additions & 39 deletions SiraUtil/Tools/FPFC/FPFCToggle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -135,8 +133,6 @@ private void EnableFPFC()

foreach (var listener in _fpfcListeners)
listener.Enabled();

DeinitializeXRLoader();
}

private void DisableFPFC()
Expand Down Expand Up @@ -179,15 +175,11 @@ private void DisableFPFC()

foreach (var listener in _fpfcListeners)
listener.Disabled();

InitializeXRLoader();
}

public void Dispose()
{
_fpfcSettings.Changed -= FPFCSettings_Changed;

InitializeXRLoader();
}

public void Tick()
Expand All @@ -199,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();
}
}
}
9 changes: 4 additions & 5 deletions SiraUtil/Zenject/Harmony/LateBoundInjector.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using HarmonyLib;
using IPA.Utilities;
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
Expand All @@ -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)
{
Expand All @@ -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>();
pcAppInit.InvokeMethod<object, PCAppInit>("TransitionToNextScene");
PCAppInit pcAppInit = SceneManager.GetSceneByName(_initialSceneName).GetRootGameObjects()[0].GetComponent<PCAppInit>();
pcAppInit.TransitionToNextScene();
});
return false;
}
Expand All @@ -36,7 +35,7 @@ internal class SiraPCScenesTransitionSetupDataSO : ScenesTransitionSetupDataSO
protected override void OnEnable()
{
var si = CreateInstance<SceneInfo>();
si.SetField("_sceneName", _initialSceneName);
si._sceneName = _initialSceneName;
Init(new SceneInfo[] { si }, Array.Empty<SceneSetupData>());
base.OnEnable();
}
Expand Down
4 changes: 2 additions & 2 deletions SiraUtil/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"id": "SiraUtil",
"name": "SiraUtil",
"author": "Auros",
"version": "3.1.7",
"version": "3.1.9",
"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"
},
Expand Down

0 comments on commit 52eb38d

Please sign in to comment.