Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of MirroredStageVariants v1.2.5
plugins/MirroredStageVariants/MirroredStageVariants.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG; using HG.Coroutines; using HG.Reflection; using HarmonyLib; using IL.RoR2; using Microsoft.CodeAnalysis; using MirroredStageVariants.Components; using MirroredStageVariants.ModCompatibility; using MirroredStageVariants.Utils; using MirroredStageVariants.Utils.Extensions; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; using Mono.Collections.Generic; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.Utils; using On.RoR2; using On.RoR2.CameraModes; using On.RoR2.UI; using R2API.Utils; using Rewired; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.CameraModes; using RoR2.ContentManagement; using RoR2.UI; using RoR2BepInExPack.GameAssetPathsBetter; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MirroredStageVariants")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d25bf8ee1aa1619f001b0924b2db2692b9816e6a")] [assembly: AssemblyProduct("MirroredStageVariants")] [assembly: AssemblyTitle("MirroredStageVariants")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class ParamCollectionAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MirroredStageVariants { internal static class Assets { private interface IAssetReference { Object Asset { get; set; } } private sealed class AssetLoadOperation { public string AssetName { get; } public AssetBundleRequest LoadRequest { get; } public IAssetReference AssetReference { get; } public bool IsDone => ((AsyncOperation)LoadRequest).isDone; public AssetLoadOperation(string assetName, AssetBundleRequest loadRequest, IAssetReference assetReference) { AssetName = assetName; LoadRequest = loadRequest ?? throw new ArgumentNullException("loadRequest"); AssetReference = assetReference ?? throw new ArgumentNullException("assetReference"); base..ctor(); } public void Update() { if (((AsyncOperation)LoadRequest).isDone) { Object asset = LoadRequest.asset; if (!Object.op_Implicit(asset)) { Log.Error("Missing asset '" + AssetName + "', check editor export!", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Assets.cs", "Update", 36); } else { AssetReference.Asset = asset; } } } } private sealed class AssetReference<T> : IAssetReference where T : Object { public T Asset; Object IAssetReference.Asset { get { return (Object)(object)Asset; } set { Asset = (T)(object)value; } } } [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <>c__DisplayClass9_0 { public AssetBundle assetBundle; } [CompilerGenerated] private sealed class <Init>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private AssetBundleCreateRequest <assetBundleLoad>5__2; private List<AssetLoadOperation> <loadOperations>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Init>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <assetBundleLoad>5__2 = null; <loadOperations>5__3 = null; <>1__state = -2; } private bool MoveNext() { <>c__DisplayClass9_0 <>c__DisplayClass9_ = default(<>c__DisplayClass9_0); switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)MirroredStageVariantsPlugin.Instance).Info.Location), "mirror_assets"); if (!File.Exists(text)) { Log.Error("Assets file not found, expected path: " + text, "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Assets.cs", "Init", 73); return false; } <assetBundleLoad>5__2 = AssetBundle.LoadFromFileAsync(text); goto IL_008c; } case 1: <>1__state = -1; goto IL_008c; case 2: { <>1__state = -1; break; } IL_008c: if (!((AsyncOperation)<assetBundleLoad>5__2).isDone) { <>2__current = null; <>1__state = 1; return true; } <>c__DisplayClass9_.assetBundle = <assetBundleLoad>5__2.assetBundle; if (!Object.op_Implicit((Object)(object)<>c__DisplayClass9_.assetBundle)) { Log.Error("Failed to load asset bundle", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Assets.cs", "Init", 88); return false; } <loadOperations>5__3 = new List<AssetLoadOperation>(); <loadOperations>5__3.Add(Assets.<Init>g__getLoadOperation|9_0<Material>("Mirror", _mirrorMaterialRef, ref <>c__DisplayClass9_)); <loadOperations>5__3.Add(Assets.<Init>g__getLoadOperation|9_0<Shader>("MirrorOverlay", _mirrorOverlayShaderRef, ref <>c__DisplayClass9_)); break; } if (<loadOperations>5__3.Count > 0) { for (int num = <loadOperations>5__3.Count - 1; num >= 0; num--) { AssetLoadOperation assetLoadOperation = <loadOperations>5__3[num]; assetLoadOperation.Update(); if (assetLoadOperation.IsDone) { <loadOperations>5__3.RemoveAt(num); } } <>2__current = null; <>1__state = 2; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly AssetReference<Material> _mirrorMaterialRef = new AssetReference<Material>(); private static readonly AssetReference<Shader> _mirrorOverlayShaderRef = new AssetReference<Shader>(); public static Material MirrorMaterial => _mirrorMaterialRef.Asset; public static Shader MirrorOverlayShader => _mirrorOverlayShaderRef.Asset; [IteratorStateMachine(typeof(<Init>d__9))] [SystemInitializer(new Type[] { })] private static IEnumerator Init() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Init>d__9(0); } } internal static class Commands { public static bool? OverrideStageIsMirrored { get; private set; } [ConCommand(commandName = "msv_force_all", helpText = "Sets or clears mirror override [mirrored/normal/random]")] private static void CCOverrideStageIsMirrored(ConCommandArgs args) { if (((ConCommandArgs)(ref args)).Count < 1) { if (OverrideStageIsMirrored.HasValue) { Debug.Log((object)("All stages forced " + (OverrideStageIsMirrored.Value ? "mirrored" : "normal"))); } else { Debug.Log((object)"No active override"); } return; } bool? flag; switch (((ConCommandArgs)(ref args)).GetArgString(0).ToLower()) { case "mirrored": case "mirror": case "m": flag = true; break; case "normal": case "n": flag = false; break; default: flag = null; break; } bool? flag2 = flag; if (OverrideStageIsMirrored != flag2) { OverrideStageIsMirrored = flag2; if (OverrideStageIsMirrored.HasValue) { Debug.Log((object)("All stages forced " + (OverrideStageIsMirrored.Value ? "mirrored" : "normal"))); } else { Debug.Log((object)"All stages mirrored override cleared"); } } } } internal static class Log { private static readonly StringBuilder _sharedStringBuilder; private static readonly object _stringBuilderLock; private static readonly int _cachedCallerPathPrefixLength; private static ManualLogSource _logSource; static Log() { _sharedStringBuilder = new StringBuilder(256); _stringBuilderLock = new object(); _cachedCallerPathPrefixLength = getCallerPathPrefixLength("D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Log.cs"); static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null) { int num = callerPath.LastIndexOf("MirroredStageVariants\\"); if (num >= 0) { return num + "MirroredStageVariants\\".Length; } Debug.LogError((object)"[MirroredStageVariants] Logger failed to determine caller path prefix length"); return 0; } } internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static string buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data) { lock (_stringBuilderLock) { return _sharedStringBuilder.Clear().Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':') .Append(callerLineNumber) .Append(" (") .Append(callerMemberName) .Append("): ") .Append(data) .ToString(); } } [Conditional("DEBUG")] internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Conditional("DEBUG")] internal static void Debug_NoCallerPrefix(object data) { _logSource.LogDebug(data); } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((level & 0x20) == 0) { _logSource.Log(level, (object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void LogType_NoCallerPrefix(LogLevel level, object data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((level & 0x20) == 0) { _logSource.Log(level, data); } } } [BepInPlugin("Gorakh.MirroredStageVariants", "MirroredStageVariants", "1.2.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class MirroredStageVariantsPlugin : BaseUnityPlugin { public const string PluginGUID = "Gorakh.MirroredStageVariants"; public const string PluginAuthor = "Gorakh"; public const string PluginName = "MirroredStageVariants"; public const string PluginVersion = "1.2.5"; internal static MirroredStageVariantsPlugin Instance { get; private set; } public static ConfigEntry<float> MirrorChance { get; private set; } public static ConfigEntry<bool> MirrorNonStages { get; private set; } public static ConfigEntry<bool> MirrorHiddenRealms { get; private set; } private void Awake() { Stopwatch stopwatch = Stopwatch.StartNew(); Log.Init(((BaseUnityPlugin)this).Logger); Instance = SingletonHelper.Assign<MirroredStageVariantsPlugin>(Instance, this); initConfigs(((BaseUnityPlugin)this).Config); stopwatch.Stop(); Log.Message_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalMilliseconds:F0}ms"); } private void OnDestroy() { Instance = SingletonHelper.Unassign<MirroredStageVariantsPlugin>(Instance, this); } private static void initConfigs(ConfigFile file) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown MirrorChance = file.Bind<float>("General", "Mirror Chance", 50f, new ConfigDescription("The percent chance that any given stage will be mirrored", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); MirrorNonStages = file.Bind<bool>("General", "Mirror Non-Stages", true, "If non-stage scenes (menu, cutscenes) should be mirrored, if enabled, they are always mirrored, if disabled, they are never mirrored."); MirrorHiddenRealms = file.Bind<bool>("General", "Mirror Hidden Realms", true, "If stages outside the normal stage one through five rotation can be mirrored."); if (RiskOfOptionsCompat.IsEnabled) { RiskOfOptionsCompat.AddConfigOptions(); } } } } namespace MirroredStageVariants.Utils { public static class AssetLoadUtils { public static AsyncOperationHandle<T> LoadAssetAsync<T>(string guid, bool autoUnload = false) where T : Object { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return LoadAssetAsync<T>(new AssetReferenceT<T>(guid), autoUnload); } public static AsyncOperationHandle<T> LoadAssetAsync<T>(AssetReferenceT<T> assetReference, bool autoUnload = false) where T : Object { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<T> result = AssetAsyncReferenceManager<T>.LoadAsset(assetReference, (AsyncReferenceHandleUnloadType)2); if (autoUnload) { result.Completed += delegate { AssetAsyncReferenceManager<T>.UnloadAsset(assetReference); }; } return result; } } public static class CameraUtils { public static bool ShouldRenderObjectAsMirrored(this Camera camera, GameObject obj) { if (StageMirrorController.CurrentlyIsMirrored && (camera.cullingMask & (1 << obj.layer)) != 0) { if (Object.op_Implicit((Object)(object)((Component)camera).GetComponent<MirrorCamera>())) { return true; } UICamera val = default(UICamera); CameraRigController val2 = ((!((Component)camera).TryGetComponent<UICamera>(ref val)) ? ((Component)camera).GetComponentInParent<CameraRigController>() : val.cameraRigController); if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.sceneCam) && Object.op_Implicit((Object)(object)((Component)val2.sceneCam).GetComponent<MirrorCamera>())) { return true; } } return false; } } public static class CoordinateUtils { public static float GetInvertedScreenXCoordinate(float coordinate, Rect space) { float xMin = ((Rect)(ref space)).xMin; float xMax = ((Rect)(ref space)).xMax; return Util.Remap(coordinate, xMin, xMax, xMax, xMin); } public static void InvertScreenXCoordinate(ref float coordinate, Rect space) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) coordinate = GetInvertedScreenXCoordinate(coordinate, space); } public static Vector2 Remap(Vector2 value, Rect inputSpace, Rect outputSpace) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) float num = Util.Remap(value.x, ((Rect)(ref inputSpace)).xMin, ((Rect)(ref inputSpace)).xMax, ((Rect)(ref outputSpace)).xMin, ((Rect)(ref outputSpace)).xMax); float num2 = Util.Remap(value.y, ((Rect)(ref inputSpace)).yMin, ((Rect)(ref inputSpace)).yMax, ((Rect)(ref outputSpace)).yMin, ((Rect)(ref outputSpace)).yMax); return new Vector2(num, num2); } } public static class TransformExtensions { [CompilerGenerated] private sealed class <GetAllChildrenRecursive>d__1 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IEnumerator, IDisposable { private int <>1__state; private Transform <>2__current; private int <>l__initialThreadId; private Transform transform; public Transform <>3__transform; private int <i>5__2; private IEnumerator<Transform> <>7__wrap2; Transform IEnumerator<Transform>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAllChildrenRecursive>d__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = transform; <>1__state = 1; return true; case 1: <>1__state = -1; <i>5__2 = 0; goto IL_00cc; case 2: { <>1__state = -3; goto IL_00a2; } IL_00cc: if (<i>5__2 < transform.childCount) { <>7__wrap2 = transform.GetChild(<i>5__2).GetAllChildrenRecursive().GetEnumerator(); <>1__state = -3; goto IL_00a2; } return false; IL_00a2: if (<>7__wrap2.MoveNext()) { Transform current = <>7__wrap2.Current; <>2__current = current; <>1__state = 2; return true; } <>m__Finally1(); <>7__wrap2 = null; <i>5__2++; goto IL_00cc; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator() { <GetAllChildrenRecursive>d__1 <GetAllChildrenRecursive>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetAllChildrenRecursive>d__ = this; } else { <GetAllChildrenRecursive>d__ = new <GetAllChildrenRecursive>d__1(0); } <GetAllChildrenRecursive>d__.transform = <>3__transform; return <GetAllChildrenRecursive>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Transform>)this).GetEnumerator(); } } public static Matrix4x4 GlobalTransformationFromLocal(this Transform transform, Matrix4x4 localTransformation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) return transform.localToWorldMatrix * localTransformation * transform.worldToLocalMatrix; } [IteratorStateMachine(typeof(<GetAllChildrenRecursive>d__1))] public static IEnumerable<Transform> GetAllChildrenRecursive(this Transform transform) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetAllChildrenRecursive>d__1(-2) { <>3__transform = transform }; } } } namespace MirroredStageVariants.Utils.Extensions { public static class AssetLoadExtensions { [CompilerGenerated] private sealed class <AsProgressCoroutine>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IProgress<float> progressReceiver; public AsyncOperation asyncOperation; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AsProgressCoroutine>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; progressReceiver.Report(asyncOperation.progress); break; } if (!asyncOperation.isDone) { <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <AsProgressCoroutine>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IProgress<float> progressReceiver; public AsyncOperationHandle asyncOperation; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AsProgressCoroutine>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; progressReceiver.Report(((AsyncOperationHandle)(ref asyncOperation)).PercentComplete); break; } if (!((AsyncOperationHandle)(ref asyncOperation)).IsDone) { <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <AsProgressCoroutine>d__4<T> : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IProgress<float> progressReceiver; public AsyncOperationHandle<T> asyncOperation; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AsProgressCoroutine>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; progressReceiver.Report(asyncOperation.PercentComplete); break; } if (!asyncOperation.IsDone) { <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void OnSuccess(this in AsyncOperationHandle handle, Action<object> onSuccess) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) StackTrace stackTrace = new StackTrace(); AsyncOperationHandle val = handle; if (((AsyncOperationHandle)(ref val)).IsDone) { handleCompleted(handle); return; } val = handle; ((AsyncOperationHandle)(ref val)).Completed += handleCompleted; void handleCompleted(AsyncOperationHandle handle) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)((AsyncOperationHandle)(ref handle)).Status == 1) { onSuccess(((AsyncOperationHandle)(ref handle)).Result); } else { Log.Error($"Failed to load asset '{((AsyncOperationHandle)(ref handle)).LocationName}'. {stackTrace}", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\AssetLoadExtensions.cs", "OnSuccess", 25); } } } public static void OnSuccess<T>(this in AsyncOperationHandle<T> handle, Action<T> onSuccess) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) StackTrace stackTrace = new StackTrace(); if (handle.IsDone) { handleCompleted(handle); return; } AsyncOperationHandle<T> val = handle; val.Completed += handleCompleted; void handleCompleted(AsyncOperationHandle<T> handle) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)handle.Status == 1) { onSuccess(handle.Result); } else { Log.Error($"Failed to load asset '{handle.LocationName}'. {stackTrace}", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\AssetLoadExtensions.cs", "OnSuccess", 51); } } } [IteratorStateMachine(typeof(<AsProgressCoroutine>d__2))] public static IEnumerator AsProgressCoroutine(this AsyncOperation asyncOperation, IProgress<float> progressReceiver) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AsProgressCoroutine>d__2(0) { asyncOperation = asyncOperation, progressReceiver = progressReceiver }; } [IteratorStateMachine(typeof(<AsProgressCoroutine>d__3))] public static IEnumerator AsProgressCoroutine(this AsyncOperationHandle asyncOperation, IProgress<float> progressReceiver) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AsProgressCoroutine>d__3(0) { asyncOperation = asyncOperation, progressReceiver = progressReceiver }; } [IteratorStateMachine(typeof(<AsProgressCoroutine>d__4<>))] public static IEnumerator AsProgressCoroutine<T>(this AsyncOperationHandle<T> asyncOperation, IProgress<float> progressReceiver) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AsProgressCoroutine>d__4<T>(0) { asyncOperation = asyncOperation, progressReceiver = progressReceiver }; } public static void Add(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperation asyncOperation) { ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine((IProgress<float>)val), val); } public static void Add(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperationHandle asyncOperation) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine((IProgress<float>)val), val); } public static void Add<T>(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperationHandle<T> asyncOperation) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine<T>((IProgress<float>)val), val); } } public static class CollectionExtensions { public static void EnsureCapacity<T>(this List<T> list, int capacity) { if (list == null) { throw new ArgumentNullException("list"); } if (list.Capacity < capacity) { list.Capacity = capacity; } } public static T Take<T>(this IList<T> list, int index) { if (list == null) { throw new ArgumentNullException("list"); } T result = list[index]; list.RemoveAt(index); return result; } public static object Take(this IList list, int index) { if (list == null) { throw new ArgumentNullException("list"); } object? result = list[index]; list.RemoveAt(index); return result; } } public static class FileExtensions { public static bool IsChildOf(this DirectoryInfo dir, DirectoryInfo other) { if (dir != null && other != null) { return dir.FullName.StartsWith(other.FullName, ignoreCase: true, CultureInfo.InvariantCulture); } return false; } } public static class PatchExtensions { public static void EmitSkipMethodCall(this ILCursor c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) c.EmitSkipMethodCall(OpCodes.Br); } public static void EmitSkipMethodCall(this ILCursor c, OpCode branchOpCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) c.EmitSkipMethodCall(branchOpCode, null); } public static void EmitSkipMethodCall(this ILCursor c, OpCode branchOpCode, Action<ILCursor> emitSkippedReturnValue) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Invalid comparison between Unknown and I4 //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) if (c == null) { throw new ArgumentNullException("c"); } if ((int)((OpCode)(ref branchOpCode)).FlowControl != 0 && (int)((OpCode)(ref branchOpCode)).FlowControl != 3) { throw new ArgumentException($"Invalid branch OpCode: {branchOpCode}"); } MethodReference val = default(MethodReference); if (c.Next == null || !ILPatternMatchingExt.MatchCallOrCallvirt(c.Next, ref val)) { Log.Error($"Failed to find method call to skip: {((MemberReference)c.Context.Method).FullName} at instruction {c.Next.SafeToString()} ({c.Index})", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "EmitSkipMethodCall", 61); return; } MethodDefinition val2 = Extensions.SafeResolve(val); if (val2 == null) { Log.Error($"Failed to resolve method '{((MemberReference)val).FullName}': {((MemberReference)c.Context.Method).FullName} at instruction {c.Next.SafeToString()} ({c.Index})", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "EmitSkipMethodCall", 69); return; } int num = ((MethodReference)val2).Parameters.Count + ((!val2.IsStatic) ? 1 : 0); bool flag = Extensions.Is((MemberReference)(object)((MethodReference)val2).ReturnType, (MemberInfo)typeof(void)); ILLabel val3 = c.DefineLabel(); if ((int)((OpCode)(ref branchOpCode)).FlowControl == 0) { c.Emit(OpCodes.Ldc_I4_0); c.Emit(((int)((OpCode)(ref branchOpCode)).OperandType == 15) ? OpCodes.Brfalse_S : OpCodes.Brfalse, (object)val3); } else { c.Emit(branchOpCode, (object)val3); } int index = c.Index; c.Index = index + 1; if (num == 0 && flag) { c.MarkLabel(val3); return; } ILLabel val4 = c.DefineLabel(); c.Emit(OpCodes.Br, (object)val4); c.MarkLabel(val3); for (int i = 0; i < num; i++) { c.Emit(OpCodes.Pop); } if (emitSkippedReturnValue != null) { emitSkippedReturnValue(c); } else if (!flag) { Log.Warning($"Skipped method ({((MemberReference)val2).FullName}) is not void, emitting default value: {((MemberReference)c.Context.Method).FullName} at instruction {c.Next.SafeToString()} ({c.Index})", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "EmitSkipMethodCall", 115); c.EmitDefaultValue(((MethodReference)val2).ReturnType); } c.MarkLabel(val4); } public static void EmitDefaultValue(this ILCursor cursor, TypeReference type) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (type == null || Extensions.Is((MemberReference)(object)type, (MemberInfo)typeof(void))) { return; } if (!type.IsValueType) { cursor.Emit(OpCodes.Ldnull); return; } switch (type.GetTypeCode()) { case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: cursor.Emit(OpCodes.Ldc_I4_0); break; case TypeCode.Int64: case TypeCode.UInt64: cursor.Emit(OpCodes.Ldc_I4_0); cursor.Emit(OpCodes.Conv_I8); break; case TypeCode.Single: cursor.Emit(OpCodes.Ldc_R4, 0f); break; case TypeCode.Double: cursor.Emit(OpCodes.Ldc_R8, 0.0); break; case TypeCode.Decimal: cursor.Emit(OpCodes.Ldsfld, typeof(decimal).GetField("Zero")); break; default: { VariableDefinition val = cursor.Context.AddVariable(type); cursor.Emit(OpCodes.Ldloca, val); cursor.Emit(OpCodes.Initobj, type); cursor.Emit(OpCodes.Ldloc, val); break; } } } public static TypeCode GetTypeCode(this TypeReference type) { if (type == null) { return TypeCode.Empty; } TypeReference val = null; TypeDefinition val2 = Extensions.SafeResolve(type); if (val2 != null && val2.IsEnum) { try { val = TypeDefinitionRocks.GetEnumUnderlyingType(val2); } catch { } } return ((MemberReference)(val ?? type)).FullName switch { "System.DBNull" => TypeCode.DBNull, "System.Boolean" => TypeCode.Boolean, "System.Char" => TypeCode.Char, "System.SByte" => TypeCode.SByte, "System.Byte" => TypeCode.Byte, "System.Int16" => TypeCode.Int16, "System.UInt16" => TypeCode.UInt16, "System.Int32" => TypeCode.Int32, "System.UInt32" => TypeCode.UInt32, "System.Int64" => TypeCode.Int64, "System.UInt64" => TypeCode.UInt64, "System.Single" => TypeCode.Single, "System.Double" => TypeCode.Double, "System.Decimal" => TypeCode.Decimal, "System.DateTime" => TypeCode.DateTime, "System.String" => TypeCode.String, _ => TypeCode.Object, }; } public static bool TryFindForeachContinueLabel(this ILCursor cursor, out ILLabel continueLabel) { ILCursor val = cursor.Clone(); int enumeratorLocalIndex = -1; MethodReference method2 = default(MethodReference); if (!val.TryGotoPrev(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, ref method2) && isEnumerableGetEnumerator(method2) }) || !val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref enumeratorLocalIndex) })) { Log.Warning("Failed to find GetEnumerator call", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "TryFindForeachContinueLabel", 256); continueLabel = null; return false; } val = cursor.Clone(); if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, enumeratorLocalIndex), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<IEnumerator>(x, "MoveNext") })) { Log.Warning("Failed to find matching MoveNext call", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "TryFindForeachContinueLabel", 266); continueLabel = null; return false; } continueLabel = val.MarkLabel(); return true; static bool isEnumerableGetEnumerator(MethodReference method) { if (method == null) { return false; } if (!string.Equals(((MemberReference)method).Name, "GetEnumerator")) { return false; } return true; } } public static string SafeToString(this Instruction instruction) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (instruction == null) { return "NULL"; } try { return ((object)instruction).ToString(); } catch { } StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder.Append(formatLabel(instruction)).Append(": "); OpCode opCode = instruction.OpCode; stringBuilder2.Append(((OpCode)(ref opCode)).Name); if (instruction.Operand != null) { stringBuilder.Append(' '); object operand = instruction.Operand; Instruction val = (Instruction)((operand is Instruction) ? operand : null); if (val == null) { if (operand is IEnumerable<Instruction> source) { stringBuilder.Append('[').Append(string.Join(", ", source.Select(formatLabel))).Append(']'); } else { stringBuilder.Append(instruction.Operand); } } else { stringBuilder.Append(formatLabel(val)); } } return stringBuilder.ToString(); static string formatLabel(Instruction instruction) { if (instruction == null) { return "IL_????"; } return $"IL_{instruction.Offset:x4}"; } } public static bool TryFindParameter(this MethodReference method, Type parameterType, string parameterName, out ParameterDefinition parameter) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (method == null) { throw new ArgumentNullException("method"); } if (parameterType == null && string.IsNullOrEmpty(parameterName)) { throw new ArgumentException("Cannot find parameter for method " + ((MemberReference)method).FullName + ": Neither parameter type or name specified"); } if (method.HasParameters) { Enumerator<ParameterDefinition> enumerator = method.Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; if ((string.IsNullOrEmpty(parameterName) || ((ParameterReference)current).Name == parameterName) && (parameterType == null || Extensions.Is((MemberReference)(object)((ParameterReference)current).ParameterType, (MemberInfo)parameterType))) { parameter = current; return true; } } } finally { ((IDisposable)enumerator).Dispose(); } } parameter = null; return false; } public static bool TryFindParameter(this MethodReference method, string name, out ParameterDefinition parameter) { return method.TryFindParameter(null, name, out parameter); } public static bool TryFindParameter(this MethodReference method, Type type, out ParameterDefinition parameter) { return method.TryFindParameter(type, null, out parameter); } public static bool TryFindParameter<T>(this MethodReference method, string name, out ParameterDefinition parameter) { return method.TryFindParameter(typeof(T), name, out parameter); } public static bool TryFindParameter<T>(this MethodReference method, out ParameterDefinition parameter) { return method.TryFindParameter(typeof(T), null, out parameter); } public static VariableDefinition AddVariable(this ILContext context, TypeReference variableType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown VariableDefinition val = new VariableDefinition(variableType); context.Method.Body.Variables.Add(val); return val; } public static VariableDefinition AddVariable(this ILContext context, Type variableType) { return context.AddVariable(context.Import(variableType)); } public static VariableDefinition AddVariable<T>(this ILContext context) { return context.AddVariable(context.Import(typeof(T))); } public static void EmitStoreStack(this ILCursor cursor, [ParamCollection] IReadOnlyList<VariableDefinition> variables) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (cursor == null) { throw new ArgumentNullException("cursor"); } if (variables == null) { throw new ArgumentNullException("variables"); } if (variables.Count != 0) { for (int num = variables.Count - 1; num >= 1; num--) { cursor.Emit(OpCodes.Stloc, variables[num]); } cursor.Emit(OpCodes.Dup); cursor.Emit(OpCodes.Stloc, variables[0]); for (int i = 1; i < variables.Count; i++) { cursor.Emit(OpCodes.Ldloc, variables[i]); } } } private static bool matchLocalIndex(int localIndex, Type variableType, ILContext ilContext) { if ((object)variableType == null) { throw new ArgumentNullException("variableType"); } if (ilContext == null) { throw new ArgumentNullException("ilContext"); } if (ilContext.Method == null || !ilContext.Method.HasBody) { return false; } if (localIndex < ilContext.Method.Body.Variables.Count) { return Extensions.Is((MemberReference)(object)((VariableReference)ilContext.Method.Body.Variables[localIndex]).VariableType, (MemberInfo)variableType); } return false; } public static bool MatchLdloc(this Instruction instruction, Type variableType, ILContext ilContext, out int localIndex) { if (instruction == null) { throw new ArgumentNullException("instruction"); } if (ILPatternMatchingExt.MatchLdloc(instruction, ref localIndex)) { return matchLocalIndex(localIndex, variableType, ilContext); } return false; } public static bool MatchLdloca(this Instruction instruction, Type variableType, ILContext ilContext, out int localIndex) { if (instruction == null) { throw new ArgumentNullException("instruction"); } if (ILPatternMatchingExt.MatchLdloca(instruction, ref localIndex)) { return matchLocalIndex(localIndex, variableType, ilContext); } return false; } public static bool MatchStloc(this Instruction instruction, Type variableType, ILContext ilContext, out int localIndex) { if (instruction == null) { throw new ArgumentNullException("instruction"); } if (ILPatternMatchingExt.MatchStloc(instruction, ref localIndex)) { return matchLocalIndex(localIndex, variableType, ilContext); } return false; } } } namespace MirroredStageVariants.Patches { internal static class CostTextMirrorFix { [SystemInitializer(new Type[] { })] private static void Init() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_Base_Common_VFX.CostHologramContent_prefab, autoUnload: false); handle.OnSuccess(delegate(GameObject costHologramContent) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) costHologramContent.AddComponent<ScaleOnAwakeIfMirrored>().ScaleMultiplier = new Vector3(-1f, 1f, 1f); }); } } internal static class HideStunEffect { [SystemInitializer(new Type[] { })] private static void Init() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_Base_Common_VFX.StunVfx_prefab, autoUnload: false); handle.OnSuccess(delegate(GameObject stunVfx) { TextMeshPro componentInChildren = stunVfx.GetComponentInChildren<TextMeshPro>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((Behaviour)componentInChildren).enabled = false; } }); } } internal static class InvertDamageNumberPositionsPatch { [SystemInitializer(new Type[] { })] private static void Init() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_Base_Core.DamageNumberManager_prefab, autoUnload: false); handle.OnSuccess(delegate(GameObject damageNumberManager) { damageNumberManager.AddComponent<FlipParticleSystemIfMirrored>(); }); handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_DLC1_CritGlassesVoid.CritGlassesVoidExecuteEffect_prefab, autoUnload: false); handle.OnSuccess(delegate(GameObject effectPrefab) { Transform val = effectPrefab.transform.Find("FakeDamageNumbers"); if (Object.op_Implicit((Object)(object)val)) { ((Component)val).gameObject.AddComponent<FlipParticleSystemIfMirrored>(); } else { Log.Error("Failed to find fake damage number emitter on CritGlassesVoidExecuteEffect", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertDamageNumberPositionsPatch.cs", "Init", 29); } }); } } internal static class InvertInputPatch { [CompilerGenerated] private static class <>O { public static hook_CollectLookInput <0>__CameraModeBase_CollectLookInput; public static Manipulator <1>__PlayerCharacterMasterController_Update; public static <>A{00000001}<Vector2> <2>__tryMirrorMoveInput; } [SystemInitializer(new Type[] { })] private static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__CameraModeBase_CollectLookInput; if (obj == null) { hook_CollectLookInput val = CameraModeBase_CollectLookInput; <>O.<0>__CameraModeBase_CollectLookInput = val; obj = (object)val; } CameraModeBase.CollectLookInput += (hook_CollectLookInput)obj; object obj2 = <>O.<1>__PlayerCharacterMasterController_Update; if (obj2 == null) { Manipulator val2 = PlayerCharacterMasterController_Update; <>O.<1>__PlayerCharacterMasterController_Update = val2; obj2 = (object)val2; } PlayerCharacterMasterController.Update += (Manipulator)obj2; } private static void CameraModeBase_CollectLookInput(orig_CollectLookInput orig, CameraModeBase self, ref CameraModeContext context, out CollectLookInputResult result) { orig.Invoke(self, ref context, ref result); if (StageMirrorController.CurrentlyIsMirrored) { result.lookInput.x *= -1f; } } private static void PlayerCharacterMasterController_Update(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) ILCursor[] array = default(ILCursor[]); if (new ILCursor(il).TryFindNext(ref array, new Func<Instruction, bool>[3] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo<Player>((Expression<Action<Player>>)((Player _) => _.GetAxis(0)))), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo<Player>((Expression<Action<Player>>)((Player _) => _.GetAxis(0)))), (Instruction x) => ILPatternMatchingExt.MatchCall(x, (MethodBase)AccessTools.DeclaredConstructor(typeof(Vector2), new Type[2] { typeof(float), typeof(float) }, false)) })) { ILCursor val = array[2]; int index = val.Index + 1; int moveInputLocalIndex = -1; if (val.TryGotoPrev(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref moveInputLocalIndex) })) { val.Index = index; if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<InputBankTest>(x, "SetRawMoveStates") })) { Log.Error("Failed to find raw move state call", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 52); } val.Emit(OpCodes.Ldloca, moveInputLocalIndex); val.EmitDelegate<<>A{00000001}<Vector2>>((<>A{00000001}<Vector2>)tryMirrorMoveInput); } else { Log.Error("Failed to find move input local index", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 67); } } else { Log.Error("Failed to find patch location", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 72); } static void tryMirrorMoveInput(ref Vector2 moveInput) { if (StageMirrorController.CurrentlyIsMirrored) { moveInput.x *= -1f; } } } } internal static class InvertScreenCoordinatesPatch { private delegate Vector3 ScreenCoordinateDelegate(Camera self, Vector3 position, MonoOrStereoscopicEye eye); private delegate Ray ScreenRayDelegate(Camera self, Vector2 pos, MonoOrStereoscopicEye eye); [SystemInitializer(new Type[] { })] private static void Init() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) new Hook((Expression<Action>)(() => ((Camera)null).WorldToScreenPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertPixelCoordinateResult)); new Hook((Expression<Action>)(() => ((Camera)null).WorldToViewportPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertNormalizedCoordinateResult)); new Hook((Expression<Action>)(() => ((Camera)null).ScreenToWorldPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertPixelCoordinateInput)); new Hook((Expression<Action>)(() => ((Camera)null).ViewportToWorldPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertNormalizedCoordinateInput)); new Hook((Expression<Action>)(() => ((Camera)null).ScreenPointToRay(default(Vector2), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenRayDelegate, Camera, Vector2, MonoOrStereoscopicEye, Ray>(invertRayPixelCoordinateInput)); new Hook((Expression<Action>)(() => ((Camera)null).ViewportPointToRay(default(Vector2), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenRayDelegate, Camera, Vector2, MonoOrStereoscopicEye, Ray>(invertRayNormalizedCoordinateInput)); } private static bool isMirrored(Camera camera) { if (StageMirrorController.CurrentlyIsMirrored) { return Object.op_Implicit((Object)(object)((Component)camera).GetComponent<MirrorCamera>()); } return false; } private static Vector3 invertPixelCoordinateResult(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Vector3 result = orig(self, position, eye); if (isMirrored(self)) { CoordinateUtils.InvertScreenXCoordinate(ref result.x, self.pixelRect); } return result; } private static Vector3 invertPixelCoordinateInput(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (isMirrored(self)) { CoordinateUtils.InvertScreenXCoordinate(ref position.x, self.pixelRect); } return orig(self, position, eye); } private static Vector3 invertNormalizedCoordinateResult(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Vector3 result = orig(self, position, eye); if (isMirrored(self)) { CoordinateUtils.InvertScreenXCoordinate(ref result.x, self.rect); } return result; } private static Vector3 invertNormalizedCoordinateInput(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (isMirrored(self)) { CoordinateUtils.InvertScreenXCoordinate(ref position.x, self.rect); } return orig(self, position, eye); } private static Ray invertRayPixelCoordinateInput(ScreenRayDelegate orig, Camera self, Vector2 pos, MonoOrStereoscopicEye eye) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (isMirrored(self)) { CoordinateUtils.InvertScreenXCoordinate(ref pos.x, self.pixelRect); } return orig(self, pos, eye); } private static Ray invertRayNormalizedCoordinateInput(ScreenRayDelegate orig, Camera self, Vector2 pos, MonoOrStereoscopicEye eye) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (isMirrored(self)) { CoordinateUtils.InvertScreenXCoordinate(ref pos.x, self.rect); } return orig(self, pos, eye); } } internal static class InvertTypewriteTextControllerPatch { [DisallowMultipleComponent] private sealed class InvertTypewriterInfo : MonoBehaviour { public static InvertTypewriterInfo Current; public TextMeshProUGUI[] InvertedLabels; } [CompilerGenerated] private static class <>O { public static hook_Start <0>__AssignStageToken_Start; public static hook_SetTypingTime <1>__TypewriteTextController_SetTypingTime; public static Manipulator <2>__TypewriteTextController_SetTypingTime_UpdateCurrentLabel; public static Func<TextMeshProUGUI, bool> <3>__shouldMirrorLabel; public static Action<TMP_Text, int> <4>__setVisibleCharactersMirrored; } [SystemInitializer(new Type[] { })] private static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown object obj = <>O.<0>__AssignStageToken_Start; if (obj == null) { hook_Start val = AssignStageToken_Start; <>O.<0>__AssignStageToken_Start = val; obj = (object)val; } AssignStageToken.Start += (hook_Start)obj; object obj2 = <>O.<1>__TypewriteTextController_SetTypingTime; if (obj2 == null) { hook_SetTypingTime val2 = TypewriteTextController_SetTypingTime; <>O.<1>__TypewriteTextController_SetTypingTime = val2; obj2 = (object)val2; } TypewriteTextController.SetTypingTime += (hook_SetTypingTime)obj2; MethodInfo methodInfo = AccessTools.GetDeclaredMethods(typeof(TypewriteTextController)).FirstOrDefault((MethodInfo m) => m.Name.StartsWith("<SetTypingTime>g__UpdateCurrentLabel|")); if ((object)methodInfo != null) { object obj3 = <>O.<2>__TypewriteTextController_SetTypingTime_UpdateCurrentLabel; if (obj3 == null) { Manipulator val3 = TypewriteTextController_SetTypingTime_UpdateCurrentLabel; <>O.<2>__TypewriteTextController_SetTypingTime_UpdateCurrentLabel = val3; obj3 = (object)val3; } new ILHook((MethodBase)methodInfo, (Manipulator)obj3); } else { Log.Error("Failed to find local function UpdateCurrentLabel", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "Init", 34); } } private static void AssignStageToken_Start(orig_Start orig, AssignStageToken self) { ((Component)self).gameObject.AddComponent<InvertTypewriterInfo>().InvertedLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[2] { self.titleText, self.subtitleText }; orig.Invoke(self); } private static void TypewriteTextController_SetTypingTime(orig_SetTypingTime orig, TypewriteTextController self, float typingTime) { InvertTypewriterInfo.Current = ((Component)self).GetComponent<InvertTypewriterInfo>(); try { orig.Invoke(self, typingTime); } finally { InvertTypewriterInfo.Current = null; } } private static void TypewriteTextController_SetTypingTime_UpdateCurrentLabel(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ParameterDefinition val2 = null; TypeDefinition val3 = null; Enumerator<ParameterDefinition> enumerator = ((MethodReference)il.Method).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; TypeReference elementType = ((ParameterReference)current).ParameterType.GetElementType(); if (((MemberReference)elementType).Name.StartsWith("<>c__DisplayClass") && ((MemberReference)elementType).DeclaringType != null && Extensions.Is((MemberReference)(object)((MemberReference)elementType).DeclaringType, (MemberInfo)typeof(TypewriteTextController))) { TypeDefinition val4 = Extensions.SafeResolve(elementType); if (val4 != null) { val3 = val4; val2 = current; break; } } } } finally { ((IDisposable)enumerator).Dispose(); } if (val2 == null) { Log.Error("Failed to find locals parameter", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime_UpdateCurrentLabel", 87); return; } FieldDefinition val5 = Extensions.FindField(val3, "currentLabel"); if (val5 == null || !Extensions.Is((MemberReference)(object)((FieldReference)val5).FieldType, (MemberInfo)typeof(TextMeshProUGUI))) { Log.Error("Failed to find currentLabel local field", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime_UpdateCurrentLabel", 94); } else if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertySetter(typeof(TMP_Text), "maxVisibleCharacters")) })) { ILLabel val6 = val.DefineLabel(); ILLabel val7 = val.DefineLabel(); val.Emit(OpCodes.Ldarg, val2); val.Emit(OpCodes.Ldfld, (FieldReference)(object)val5); val.EmitDelegate<Func<TextMeshProUGUI, bool>>((Func<TextMeshProUGUI, bool>)shouldMirrorLabel); val.Emit(OpCodes.Brtrue, (object)val6); int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Br, (object)val7); val.MarkLabel(val6); val.MoveAfterLabels(); val.EmitDelegate<Action<TMP_Text, int>>((Action<TMP_Text, int>)setVisibleCharactersMirrored); val.MarkLabel(val7); } else { Log.Error("Failed to find patch location", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime_UpdateCurrentLabel", 132); } static void setVisibleCharactersMirrored(TMP_Text label, int maxVisibleCharacters) { label.firstVisibleCharacter = label.text.Length - maxVisibleCharacters; } static bool shouldMirrorLabel(TextMeshProUGUI label) { if (StageMirrorController.CurrentlyIsMirrored && Object.op_Implicit((Object)(object)InvertTypewriterInfo.Current)) { return Array.IndexOf(InvertTypewriterInfo.Current.InvertedLabels, label) != -1; } return false; } } } internal static class MirrorAudioPatch { private delegate int SetObjectPositionDelegate(ulong akObjectId, Vector3 position, Vector3 forward, Vector3 up); private sealed class AkObjectData { public readonly ulong Id; public readonly GameObject GameObject; public readonly AkGameObj AkObj; public Vector3 Position { get; private set; } public Vector3 Forward { get; private set; } public Vector3 Up { get; private set; } public AkObjectData(ulong id, GameObject gameObject) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) Id = id; GameObject = gameObject; AkObj = gameObject.GetComponent<AkGameObj>(); Transform transform = gameObject.transform; Position = (Object.op_Implicit((Object)(object)AkObj) ? AkObj.GetPosition() : transform.position); Forward = (Object.op_Implicit((Object)(object)AkObj) ? AkObj.GetForward() : transform.forward); Up = (Object.op_Implicit((Object)(object)AkObj) ? AkObj.GetUpward() : transform.up); } private bool tryGetListenerMirrorTransformation(out Matrix4x4 mirrorTransform) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) MirrorCamera mirrorCamera = default(MirrorCamera); foreach (AkAudioListener item in (Object.op_Implicit((Object)(object)AkObj) && !AkObj.IsUsingDefaultListeners) ? AkObj.ListenerList : ((BaseListenerList)AkAudioListener.DefaultListeners).ListenerList) { if (((Component)item).TryGetComponent<MirrorCamera>(ref mirrorCamera)) { mirrorTransform = mirrorCamera.MirrorAroundCameraTransformation; return true; } } mirrorTransform = Matrix4x4.identity; return false; } public void UpdatePosition(Vector3 position, Vector3 forward, Vector3 up) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Position = position; Forward = forward; Up = up; } public void GetMirrorPosition(out Vector3 position, out Vector3 forward, out Vector3 up) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) position = Position; forward = Forward; up = Up; if (tryGetListenerMirrorTransformation(out var mirrorTransform)) { position = ((Matrix4x4)(ref mirrorTransform)).MultiplyPoint(position); forward = ((Matrix4x4)(ref mirrorTransform)).MultiplyVector(forward); up = ((Matrix4x4)(ref mirrorTransform)).MultiplyVector(up); } } public AKRESULT UpdateMirrorPosition() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) GetMirrorPosition(out var position, out var forward, out var up); if (_origSetPosition == null) { Log.Error("Missing set position function", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\MirrorAudioPatch.cs", "UpdateMirrorPosition", 85); return (AKRESULT)2; } return (AKRESULT)_origSetPosition(Id, position, forward, up); } } private delegate void orig_AkSoundEngine_PostRegisterGameObjUserHook(AKRESULT result, GameObject gameObject, ulong id); private delegate void orig_AkSoundEngine_PostUnregisterGameObjUserHook(AKRESULT result, GameObject gameObject, ulong id); private delegate void orig_AkSoundEngine_ClearRegisteredGameObjects(); private static SetObjectPositionDelegate _origSetPosition; private static readonly Dictionary<ulong, AkObjectData> _akObjects = new Dictionary<ulong, AkObjectData>(); [SystemInitializer(new Type[] { })] private static void Init() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) _origSetPosition = new NativeDetour((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEnginePINVOKE.CSharp_SetObjectPosition(0uL, default(Vector3), default(Vector3), default(Vector3)))), (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine_SetObjectPosition(0uL, default(Vector3), default(Vector3), default(Vector3))))).GenerateTrampoline<SetObjectPositionDelegate>(); new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostRegisterGameObjUserHook((AKRESULT)0, (GameObject)null, 0uL))), (Delegate)new Action<orig_AkSoundEngine_PostRegisterGameObjUserHook, AKRESULT, GameObject, ulong>(AkSoundEngine_PostRegisterGameObjUserHook)); new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostUnregisterGameObjUserHook((AKRESULT)0, (GameObject)null, 0uL))), (Delegate)new Action<orig_AkSoundEngine_PostUnregisterGameObjUserHook, AKRESULT, GameObject, ulong>(AkSoundEngine_PostUnregisterGameObjUserHook)); new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.ClearRegisteredGameObjects())), (Delegate)new Action<orig_AkSoundEngine_ClearRegisteredGameObjects>(AkSoundEngine_ClearRegisteredGameObjects)); MirrorCamera.OnMirrorTransformationChanged += onCameraMirrorTransformationChanged; } private static void onCameraMirrorTransformationChanged() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) foreach (AkObjectData value in _akObjects.Values) { value.UpdateMirrorPosition(); } } private static void AkSoundEngine_PostRegisterGameObjUserHook(orig_AkSoundEngine_PostRegisterGameObjUserHook orig, AKRESULT result, GameObject gameObject, ulong id) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 orig(result, gameObject, id); if ((int)result == 1 && Object.op_Implicit((Object)(object)gameObject) && !_akObjects.ContainsKey(id)) { _akObjects.Add(id, new AkObjectData(id, gameObject)); } } private static void AkSoundEngine_PostUnregisterGameObjUserHook(orig_AkSoundEngine_PostUnregisterGameObjUserHook orig, AKRESULT result, GameObject gameObject, ulong id) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 orig(result, gameObject, id); if ((int)result == 1) { _akObjects.Remove(id); } } private static void AkSoundEngine_ClearRegisteredGameObjects(orig_AkSoundEngine_ClearRegisteredGameObjects orig) { orig(); _akObjects.Clear(); } private static int AkSoundEngine_SetObjectPosition(ulong akObjectId, Vector3 position, Vector3 forward, Vector3 up) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (_akObjects.TryGetValue(akObjectId, out var value)) { value.UpdatePosition(position, forward, up); value.GetMirrorPosition(out position, out forward, out up); } return _origSetPosition(akObjectId, position, forward, up); } } internal static class MirrorEffectsPatch { [SystemInitializer(new Type[] { typeof(EffectCatalog) })] private static void Init() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) List<TMP_Text> list = new List<TMP_Text>(); for (EffectIndex val = (EffectIndex)0; (int)val < EffectCatalog.effectCount; val = (EffectIndex)(val + 1)) { EffectDef effectDef = EffectCatalog.GetEffectDef(val); if (effectDef == null) { continue; } GameObject prefab = effectDef.prefab; if (!Object.op_Implicit((Object)(object)prefab)) { continue; } list.Clear(); prefab.GetComponentsInChildren<TMP_Text>(list); foreach (TMP_Text item in list) { if (((Component)item).gameObject.layer == LayerIndex.uiWorldSpace.intVal && !Object.op_Implicit((Object)(object)((Component)item).GetComponent<MirrorTextLabelIfMirrored>())) { ((Component)item).gameObject.AddComponent<MirrorTextLabelIfMirrored>(); } } } } } } namespace MirroredStageVariants.ModCompatibility { internal static class RiskOfOptionsCompat { public static bool IsEnabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfigOptions() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) ModSettingsManager.AddOption((BaseOption)new StepSliderOption(MirroredStageVariantsPlugin.MirrorChance, new StepSliderConfig { formatString = "{0}%", min = 0f, max = 100f, increment = 0.1f }), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(MirroredStageVariantsPlugin.MirrorNonStages), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(MirroredStageVariantsPlugin.MirrorHiddenRealms), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants"); ModSettingsManager.SetModDescription("Options for Mirrored Stage Variants", "Gorakh.MirroredStageVariants", "Mirrored Stage Variants"); FileInfo fileInfo = null; DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)MirroredStageVariantsPlugin.Instance).Info.Location)); do { FileInfo[] files = directoryInfo.GetFiles("icon.png", SearchOption.TopDirectoryOnly); if (files != null && files.Length != 0) { fileInfo = files[0]; break; } directoryInfo = directoryInfo.Parent; } while (directoryInfo != null && directoryInfo.Exists && !string.Equals(directoryInfo.Name, "plugins", StringComparison.OrdinalIgnoreCase)); if (fileInfo != null) { Texture2D val = new Texture2D(256, 256); if (ImageConversion.LoadImage(val, File.ReadAllBytes(fileInfo.FullName))) { Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); ((Object)obj).name = "MirroredStageVariantsIcon"; ModSettingsManager.SetModIcon(obj, "Gorakh.MirroredStageVariants", "Mirrored Stage Variants"); } } } } } namespace MirroredStageVariants.Components { [DisallowMultipleComponent] public sealed class FlipParticleSystemIfMirrored : MonoBehaviour { private ParticleSystemRenderer _particleRenderer; private bool _isFlipped; private void Awake() { _particleRenderer = ((Component)this).GetComponent<ParticleSystemRenderer>(); } private void OnEnable() { updateIsFlipped(); } private void FixedUpdate() { updateIsFlipped(); } private void updateIsFlipped() { bool currentlyIsMirrored = StageMirrorController.CurrentlyIsMirrored; setFlipped(currentlyIsMirrored); } private void setFlipped(bool flipped) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (_isFlipped != flipped) { _isFlipped = flipped; if (Object.op_Implicit((Object)(object)_particleRenderer)) { Vector3 flip = _particleRenderer.flip; flip.x = (_isFlipped ? 1f : 0f); _particleRenderer.flip = flip; } } } } public sealed class MirrorCamera : MonoBehaviour { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_Awake <>9__0_0; internal void <Init>b__0_0(orig_Awake orig, SceneCamera self) { orig.Invoke(self); ((Component)self).gameObject.AddComponent<MirrorCamera>(); } } private Matrix4x4 _mirrorAroundCameraTransformation = Matrix4x4.identity; public Matrix4x4 MirrorAroundCameraTransformation { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return _mirrorAroundCameraTransformation; } private set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!((Matrix4x4)(ref _mirrorAroundCameraTransformation)).Equals(value)) { _mirrorAroundCameraTransformation = value; MirrorCamera.OnMirrorTransformationChanged?.Invoke(); } } } public static event Action OnMirrorTransformationChanged; [SystemInitializer(new Type[] { })] private static void Init() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { hook_Awake val = delegate(orig_Awake orig, SceneCamera self) { orig.Invoke(self); ((Component)self).gameObject.AddComponent<MirrorCamera>(); }; <>c.<>9__0_0 = val; obj = (object)val; } SceneCamera.Awake += (hook_Awake)obj; } private void OnEnable() { recalculateMirrorTransformation(); } private void Update() { recalculateMirrorTransformation(); } private void recalculateMirrorTransformation() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (StageMirrorController.CurrentlyIsMirrored) { MirrorAroundCameraTransformation = ((Component)this).transform.GlobalTransformationFromLocal(Matrix4x4.Scale(new Vector3(-1f, 1f, 1f))); } else { MirrorAroundCameraTransformation = Matrix4x4.identity; } } private void OnRenderImage(RenderTexture source, RenderTexture destination) { Material mirrorMaterial = Assets.MirrorMaterial; if (StageMirrorController.CurrentlyIsMirrored && Object.op_Implicit((Object)(object)mirrorMaterial)) { Graphics.Blit((Texture)(object)source, destination, mirrorMaterial); } else { Graphics.Blit((Texture)(object)source, destination); } } } [DisallowMultipleComponent] public sealed class MirrorTextLabelIfMirrored : MonoBehaviour { private bool _isRenderingAsMirrored; private Vector3 _originalScale; private void OnEnable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Camera.onPreRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(onPreRender)); Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(onPostRender)); } private void OnDisable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Camera.onPreRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(onPreRender)); Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(onPostRender)); } private void onPreRender(Camera cam) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) _isRenderingAsMirrored = cam.ShouldRenderObjectAsMirrored(((Component)this).gameObject); if (_isRenderingAsMirrored) { _originalScale = ((Component)this).transform.localScale; Vector3 originalScale = _originalScale; originalScale.x *= -1f; ((Component)this).transform.localScale = originalScale; } } private void onPostRender(Camera cam) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (_isRenderingAsMirrored) { ((Component)this).transform.localScale = _originalScale; _isRenderingAsMirrored = false; } } } [DefaultExecutionOrder(-1)] public sealed class ScaleOnAwakeIfMirrored : MonoBehaviour { public Vector3 ScaleMultiplier = Vector3.one; private void Awake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (StageMirrorController.CurrentlyIsMirrored) { ((Component)this).transform.localScale = Vector3.Scale(((Component)this).transform.localScale, ScaleMultiplier); } } } public sealed class StageMirrorController : MonoBehaviour { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_OnEnable <>9__0_0; internal void <Init>b__0_0(orig_OnEnable orig, Stage self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<StageMirrorController>())) { ((Component)self).gameObject.AddComponent<StageMirrorController>(); } } } private static StageMirrorController _instance; public static StageMirrorController Instance => _instance; public static bool CurrentlyIsMirrored { get { if (!CanMirrorScene(SceneCatalog.mostRecentSceneDef)) { return false; } if (!Object.op_Implicit((Object)(object)_instance)) { return MirroredStageVariantsPlugin.MirrorNonStages.Value; } if (Commands.OverrideStageIsMirrored.HasValue) { return Commands.OverrideStageIsMirrored.Value; } return _instance.IsMirrored; } } public bool IsMirrored { get; private set; } [SystemInitializer(new Type[] { })] private static void Init() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { hook_OnEnable val = delegate(orig_OnEnable orig, Stage self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<StageMirrorController>())) { ((Component)self).gameObject.AddComponent<StageMirrorController>(); } }; <>c.<>9__0_0 = val; obj = (object)val; } Stage.OnEnable += (hook_OnEnable)obj; } public static bool CanMirrorScene(SceneDef scene) { if (!Object.op_Implicit((Object)(object)scene)) { return false; } string cachedName = scene.cachedName; if (cachedName == "lobby" || cachedName == "logbook") { return false; } if (MirroredStageVariantsPlugin.MirrorHiddenRealms.Value) { return true; } if (scene.stageOrder > 0) { return scene.stageOrder <= 5; } return false; } private void OnEnable() { SingletonHelper.Assign<StageMirrorController>(ref _instance, this); } private void OnDisable() { SingletonHelper.Unassign<StageMirrorController>(ref _instance, this); } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown Xoroshiro128Plus val = RoR2Application.rng; if (Object.op_Implicit((Object)(object)Run.instance)) { val = new Xoroshiro128Plus((ulong)(Run.instance.NetworkstartTimeUtc._binaryValue + Run.instance.stageClearCount)); } IsMirrored = val.nextNormalizedFloat <= MirroredStageVariantsPlugin.MirrorChance.Value / 100f; } } }