Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MirroredStageVariants v1.2.6
plugins/MirroredStageVariants/MirroredStageVariants.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using 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.UI; using R2API.Utils; using Rewired; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; 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+e00ecf719ef47751ed7ab1f98a3765942f0be60f")] [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, string 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(string 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(string data) { _logSource.LogDebug((object)data); } internal static void Error(string 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(string data) { _logSource.LogError((object)data); } internal static void Fatal(string 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(string data) { _logSource.LogFatal((object)data); } internal static void Info(string 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(string data) { _logSource.LogInfo((object)data); } internal static void Message(string 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(string data) { _logSource.LogMessage((object)data); } internal static void Warning(string 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(string data) { _logSource.LogWarning((object)data); } internal static void LogType(LogLevel level, string 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, string 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, (object)data); } } } [BepInPlugin("Gorakh.MirroredStageVariants", "MirroredStageVariants", "1.2.6")] [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.6"; 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 AddressableUtil { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AsyncOperationHandle<T> LoadTempAssetAsync<T>(string assetKey) where T : Object { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return AssetAsyncReferenceManager<T>.LoadAsset(new AssetReferenceT<T>(assetKey), (AsyncReferenceHandleUnloadType)0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AsyncOperationHandle<T> LoadTempAssetAsync<T>(AssetReferenceT<T> assetReference) where T : Object { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return AssetAsyncReferenceManager<T>.LoadAsset(assetReference, (AsyncReferenceHandleUnloadType)0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AsyncOperationHandle<T> LoadAssetAsync<T>(string assetKey, AsyncReferenceHandleUnloadType unloadType = 2) where T : Object { //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) return AssetAsyncReferenceManager<T>.LoadAsset(new AssetReferenceT<T>(assetKey), unloadType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AsyncOperationHandle<T> LoadAssetAsync<T>(AssetReferenceT<T> assetReference, AsyncReferenceHandleUnloadType unloadType = 2) where T : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return AssetAsyncReferenceManager<T>.LoadAsset(assetReference, unloadType); } } 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) && MirrorCamera.IsMirrored(val2.sceneCam)) { 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__1<TProgress> : IEnumerator<object>, IEnumerator, IDisposable where TProgress : IProgress<float> { private int <>1__state; private object <>2__current; public TProgress 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__1(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; ref TProgress reference = ref progressReceiver; TProgress val = default(TProgress); if (val == null) { val = reference; reference = ref val; } reference.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__2<TProgress> : IEnumerator<object>, IEnumerator, IDisposable where TProgress : IProgress<float> { private int <>1__state; private object <>2__current; public TProgress 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__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; ref TProgress reference = ref progressReceiver; TProgress val = default(TProgress); if (val == null) { val = reference; reference = ref val; } reference.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__3<T, TProgress> : IEnumerator<object>, IEnumerator, IDisposable where TProgress : IProgress<float> { private int <>1__state; private object <>2__current; public TProgress 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__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; ref TProgress reference = ref progressReceiver; TProgress val = default(TProgress); if (val == null) { val = reference; reference = ref val; } reference.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<T>(this in AsyncOperationHandle<T> handle, Action<T> onSuccess) { //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_0026: 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) if (handle.IsDone) { handleCompleted(in handle); return; } AsyncOperationHandle<T> val = handle; val.Completed += onCompleted; void handleCompleted(in AsyncOperationHandle<T> handle) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) //IL_0017: 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_002e: Unknown result type (might be due to invalid IL or missing references) if ((int)handle.Status != 1) { string text = handle.LocationName; if (string.IsNullOrEmpty(text)) { text = handle.DebugName; if (string.IsNullOrEmpty(text)) { text = "Unknown handle (" + typeof(T).FullName + ")"; } } Log.Error("Failed to load asset from location/handle: '" + text + "'", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\AssetLoadExtensions.cs", "OnSuccess", 33); } else { onSuccess(handle.Result); } } void onCompleted(AsyncOperationHandle<T> handle) { handleCompleted(in handle); } } [IteratorStateMachine(typeof(<AsProgressCoroutine>d__1<>))] public static IEnumerator AsProgressCoroutine<TProgress>(this AsyncOperation asyncOperation, TProgress progressReceiver) where TProgress : IProgress<float> { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AsProgressCoroutine>d__1<TProgress>(0) { asyncOperation = asyncOperation, progressReceiver = progressReceiver }; } [IteratorStateMachine(typeof(<AsProgressCoroutine>d__2<>))] public static IEnumerator AsProgressCoroutine<TProgress>(this AsyncOperationHandle asyncOperation, TProgress progressReceiver) where TProgress : IProgress<float> { //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__2<TProgress>(0) { asyncOperation = asyncOperation, progressReceiver = progressReceiver }; } [IteratorStateMachine(typeof(<AsProgressCoroutine>d__3<, >))] public static IEnumerator AsProgressCoroutine<T, TProgress>(this AsyncOperationHandle<T> asyncOperation, TProgress progressReceiver) where TProgress : IProgress<float> { //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<T, TProgress>(0) { asyncOperation = asyncOperation, progressReceiver = progressReceiver }; } public static void AddProgressCoroutine(this ParallelProgressCoroutine parallelProgressCoroutine, Func<ReadableProgress<float>, IEnumerator> coroutine) { ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(coroutine(val), val); } public static void AddProgressCoroutine<TArg>(this ParallelProgressCoroutine parallelProgressCoroutine, Func<TArg, ReadableProgress<float>, IEnumerator> coroutine, TArg arg) { ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(coroutine(arg, val), val); } public static void Add(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperation asyncOperation) { ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine<ReadableProgress<float>>(val), val); } public static void Add(this ParallelProgressCoroutine parallelProgressCoroutine, in AsyncOperationHandle asyncOperation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine<ReadableProgress<float>>(val), val); } public static void Add<T>(this ParallelProgressCoroutine parallelProgressCoroutine, in AsyncOperationHandle<T> asyncOperation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) ReadableProgress<float> val = new ReadableProgress<float>(); parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine<T, ReadableProgress<float>>(val), val); } public static bool AssertLoaded(this in AsyncOperationHandle asyncOperation, string assetName = null, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle val = asyncOperation; if (((AsyncOperationHandle)(ref val)).IsValid()) { val = asyncOperation; if ((int)((AsyncOperationHandle)(ref val)).Status == 1) { val = asyncOperation; if (((AsyncOperationHandle)(ref val)).Result != null) { return true; } } } string text = assetName; if (text == null) { val = asyncOperation; text = ((AsyncOperationHandle)(ref val)).DebugName; } val = asyncOperation; object arg; if (!((AsyncOperationHandle)(ref val)).IsValid()) { arg = "Invalid Handle"; } else { val = asyncOperation; arg = ((AsyncOperationHandle)(ref val)).OperationException; } Log.Error($"Failed to load asset {text}: {arg}", callerPath, callerMemberName, callerLineNumber); return false; } public static bool AssertLoaded<T>(this in AsyncOperationHandle<T> asyncOperation, string assetName = null, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!asyncOperation.IsValid() || (int)asyncOperation.Status != 1 || asyncOperation.Result == null) { Log.Error(string.Format("Failed to load asset {0}: {1}", assetName ?? asyncOperation.DebugName, asyncOperation.IsValid() ? ((object)asyncOperation.OperationException) : ((object)"Invalid Handle")), callerPath, callerMemberName, callerLineNumber); return false; } return true; } } 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 = AddressableUtil.LoadAssetAsync<GameObject>(RoR2_Base_Common_VFX.CostHologramContent_prefab, (AsyncReferenceHandleUnloadType)2); 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 = AddressableUtil.LoadAssetAsync<GameObject>(RoR2_Base_Common_VFX.StunVfx_prefab, (AsyncReferenceHandleUnloadType)2); 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 = AddressableUtil.LoadAssetAsync<GameObject>(RoR2_Base_Core.DamageNumberManager_prefab, (AsyncReferenceHandleUnloadType)2); handle.OnSuccess(delegate(GameObject damageNumberManager) { damageNumberManager.AddComponent<FlipParticleSystemIfMirrored>(); }); handle = AddressableUtil.LoadAssetAsync<GameObject>(RoR2_DLC1_CritGlassesVoid.CritGlassesVoidExecuteEffect_prefab, (AsyncReferenceHandleUnloadType)2); 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 Manipulator <0>__PlayerCharacterMasterController_Update; public static <>A{00000008}<PlayerCharacterMasterController, Vector2> <1>__tryMirrorMoveInput; } [SystemInitializer(new Type[] { })] private static void Init() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0043: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0077: Expected O, but got Unknown MethodInfo method = typeof(CameraRigController).GetMethod("EarlyUpdate", (BindingFlags)(-1)); if (method != null) { new Hook((MethodBase)method, (Delegate)new hook_EarlyUpdate(CameraRigController_EarlyUpdate), new HookConfig { Priority = 100 }); } else { Log.Error("Failed to find method CameraRigController.EarlyUpdate", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "Init", 27); } object obj = <>O.<0>__PlayerCharacterMasterController_Update; if (obj == null) { Manipulator val = PlayerCharacterMasterController_Update; <>O.<0>__PlayerCharacterMasterController_Update = val; obj = (object)val; } PlayerCharacterMasterController.Update += (Manipulator)obj; } private static void CameraRigController_EarlyUpdate(orig_EarlyUpdate orig, CameraRigController self) { UserProfile userProfile = self.cameraModeContext.viewerInfo.userProfile; if (userProfile == null || !MirrorCamera.IsMirrored(self.sceneCam)) { orig.Invoke(self); return; } bool mouseLookInvertX = invertAndReturnOriginal(ref userProfile.mouseLookInvertX); bool stickLookInvertX = invertAndReturnOriginal(ref userProfile.stickLookInvertX); bool gyroLookInvertX = invertAndReturnOriginal(ref userProfile.gyroLookInvertX); using (new InvertScreenCoordinatesPatch.DisableScope()) { try { orig.Invoke(self); } finally { userProfile.mouseLookInvertX = mouseLookInvertX; userProfile.stickLookInvertX = stickLookInvertX; userProfile.gyroLookInvertX = gyroLookInvertX; } } static bool invertAndReturnOriginal(ref bool value) { bool result = value; value = !value; return result; } } 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) //IL_0113: 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", 90); } val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloca, moveInputLocalIndex); val.EmitDelegate<<>A{00000008}<PlayerCharacterMasterController, Vector2>>((<>A{00000008}<PlayerCharacterMasterController, Vector2>)tryMirrorMoveInput); } else { Log.Error("Failed to find move input local index", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 117); } } else { Log.Error("Failed to find patch location", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 122); } static void tryMirrorMoveInput(PlayerCharacterMasterController playerMasterController, ref Vector2 moveInput) { if (Object.op_Implicit((Object)(object)playerMasterController)) { NetworkUser networkUser = playerMasterController.networkUser; if (Object.op_Implicit((Object)(object)networkUser)) { CameraRigController cameraRigController = networkUser.cameraRigController; if (Object.op_Implicit((Object)(object)cameraRigController) && MirrorCamera.IsMirrored(cameraRigController.sceneCam)) { moveInput.x *= -1f; } } } } } } internal static class InvertScreenCoordinatesPatch { [StructLayout(LayoutKind.Sequential, Size = 1)] public readonly ref struct DisableScope { public DisableScope() { _disablePatchCount++; } public void Dispose() { _disablePatchCount--; } } private delegate Vector3 ScreenCoordinateDelegate(Camera self, Vector3 position, MonoOrStereoscopicEye eye); private delegate Ray ScreenRayDelegate(Camera self, Vector2 pos, MonoOrStereoscopicEye eye); private static uint _disablePatchCount; [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 (_disablePatchCount == 0) { return MirrorCamera.IsMirrored(camera); } 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); } } public static bool IsMirrored(Camera camera) { if (StageMirrorController.CurrentlyIsMirrored && Object.op_Implicit((Object)(object)camera)) { return Object.op_Implicit((Object)(object)((Component)camera).GetComponent<MirrorCamera>()); } return false; } } [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 du