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 EntranceTeleportOptimizations v1.0.0
BepInEx/plugins/EntranceTeleportOptimizations.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntranceTeleportOptimizations.Dependency; using EntranceTeleportOptimizations.Utils.IL; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using Unity.Netcode; using UnityEngine; using UnityEngine.Pool; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.AccessibilityModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AndroidJNIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AnimationModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AssetBundleModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ClothModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ClusterInputModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ClusterRendererModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ContentLoadModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.CrashReportingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.DirectorModule")] [assembly: IgnoresAccessChecksTo("UnityEngine")] [assembly: IgnoresAccessChecksTo("UnityEngine.DSPGraphModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GameCenterModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ProfilerModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SharedInternalsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpriteMaskModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpriteShapeModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.StreamingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SubstanceModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SubsystemsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TerrainModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TerrainPhysicsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreFontEngineModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreTextEngineModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TextRenderingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TilemapModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TLSModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.UIElementsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UmbraModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsCommonModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityConnectModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityCurlModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityTestProtocolModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAssetBundleModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAudioModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestTextureModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestWWWModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VehiclesModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VFXModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VideoModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VirtualTexturingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VRModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.WindModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.XRModule")] [assembly: AssemblyCompany("mattymatty")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+48fe2bfdaf19225cb1af1d5ca58f26e74960e40f")] [assembly: AssemblyProduct("EntranceTeleportOptimizations")] [assembly: AssemblyTitle("EntranceTeleportOptimizations - Plugin")] [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 IsUnmanagedAttribute : 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 EntranceTeleportOptimizations { [BepInPlugin("mattymatty.EntranceTeleportOptimizations", "EntranceTeleportOptimizations", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntranceTeleportOptimizations : BaseUnityPlugin { internal static class PluginConfig { internal static ConfigEntry<bool> PatchPrefabIDsConfig; internal static ConfigEntry<bool> RenameInteriorGameObjectsConfig; internal static ConfigEntry<bool> DetectEnemyBothSidesConfig; internal static ConfigEntry<float> InsideEnemyDetectionRangeConfig; internal static ConfigEntry<float> OutsideEnemyDetectionRangeConfig; internal const float InsideEnemyDetectionRange = 7.7f; internal const float OutsideEnemyDetectionRange = 30f; internal static void Init() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown ConfigFile config = ((BaseUnityPlugin)INSTANCE).Config; config.SaveOnConfigSet = false; PatchPrefabIDsConfig = config.Bind<bool>("Fixes", "fix_prefab_IDs", true, "force all interior teleports ( except main ) to an ID of 1 on spawn"); DetectEnemyBothSidesConfig = config.Bind<bool>("Extra", "detect_enemy_both_sides", false, "allow interior teleports to detect enemies on the outside"); InsideEnemyDetectionRangeConfig = config.Bind<float>("Extra", "inside_enemy_detection_range", 7.7f, new ConfigDescription("how close an enemy has to be from the teleport for it to show [Near activity detected!]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>())); OutsideEnemyDetectionRangeConfig = config.Bind<float>("Extra", "outside_enemy_detection_range", 30f, new ConfigDescription("how close an enemy has to be from the teleport for it to show [Near activity detected!]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>())); RenameInteriorGameObjectsConfig = config.Bind<bool>("Debug", "rename_interior_gameobjects", false, "rename interior teleports to match their connected exterior teleports"); if (LethalConfigProxy.Enabled) { LethalConfigProxy.AddConfig(PatchPrefabIDsConfig, requiresRestart: true); LethalConfigProxy.AddConfig(DetectEnemyBothSidesConfig, requiresRestart: true); LethalConfigProxy.AddConfig(InsideEnemyDetectionRangeConfig); LethalConfigProxy.AddConfig(OutsideEnemyDetectionRangeConfig); LethalConfigProxy.AddConfig(RenameInteriorGameObjectsConfig, requiresRestart: true); } config.SaveOnConfigSet = true; CleanAndSave(); } internal static void CleanAndSave() { ConfigFile config = ((BaseUnityPlugin)INSTANCE).Config; PropertyInfo propertyInfo = AccessTools.Property(((object)config).GetType(), "OrphanedEntries"); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(config, null); dictionary.Clear(); config.Save(); } } internal static readonly ISet<Hook> Hooks = new HashSet<Hook>(); internal static readonly Harmony Harmony = new Harmony("mattymatty.EntranceTeleportOptimizations"); public const string GUID = "mattymatty.EntranceTeleportOptimizations"; public const string NAME = "EntranceTeleportOptimizations"; public const string VERSION = "1.0.0"; internal static ManualLogSource Log; public static EntranceTeleportOptimizations INSTANCE { get; private set; } private void Awake() { INSTANCE = this; Log = ((BaseUnityPlugin)this).Logger; try { if (LobbyCompatibilityChecker.Enabled) { LobbyCompatibilityChecker.Init(); } Log.LogInfo((object)"Initializing Configs"); PluginConfig.Init(); Log.LogInfo((object)"Patching Methods"); Harmony.PatchAll(); Log.LogInfo((object)"EntranceTeleportOptimizations v1.0.0 Loaded!"); } catch (Exception ex) { Log.LogError((object)("Exception while initializing: \n" + ex)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "mattymatty.EntranceTeleportOptimizations"; public const string PLUGIN_NAME = "EntranceTeleportOptimizations"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace EntranceTeleportOptimizations.Utils.IL { internal class ILInjector { [CompilerGenerated] private sealed class <GetRelativeInstructions>d__34 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; public ILInjector <>4__this; private int offset; public int <>3__offset; private int size; public int <>3__size; private int <i>5__2; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRelativeInstructions>d__34(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ILInjector iLInjector = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < size) { <>2__current = iLInjector.instructions[iLInjector.index + offset + <i>5__2]; <>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(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <GetRelativeInstructions>d__34 <GetRelativeInstructions>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetRelativeInstructions>d__ = this; } else { <GetRelativeInstructions>d__ = new <GetRelativeInstructions>d__34(0) { <>4__this = <>4__this }; } <GetRelativeInstructions>d__.offset = <>3__offset; <GetRelativeInstructions>d__.size = <>3__size; return <GetRelativeInstructions>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } private const string INVALID = "Injector is invalid"; private List<CodeInstruction> instructions = instructions.ToList(); private ILGenerator generator; private int index; private int matchEnd; public int Index { get { return index; } set { index = value; } } public bool IsValid { get { if (instructions != null) { return IsIndexValid(index); } return false; } } public CodeInstruction Instruction { get { if (!IsIndexInRange(index)) { return null; } return instructions[index]; } set { if (!IsIndexInRange(index)) { throw new InvalidOperationException($"Current index {index} is out of range of instruction count {instructions.Count}"); } instructions[index] = value; } } public CodeInstruction LastMatchedInstruction { get { int num = matchEnd - 1; if (!IsIndexInRange(num)) { return null; } return instructions[num]; } set { int num = matchEnd - 1; if (!IsIndexInRange(num)) { throw new InvalidOperationException($"Last matched index {index} is out of range of instruction count {instructions.Count}"); } instructions[num] = value; } } public ICollection<CodeInstruction> Instructions => instructions.AsReadOnly(); public ILInjector(IEnumerable<CodeInstruction> instructions, ILGenerator generator = null) { this.generator = generator; matchEnd = -1; base..ctor(); } public ILInjector GoToStart() { matchEnd = index; index = 0; return this; } public ILInjector GoToEnd() { matchEnd = index; index = instructions.Count; return this; } public ILInjector Forward(int offset) { if (!IsValid) { return this; } matchEnd = index; index = Math.Clamp(index + offset, -1, instructions.Count); return this; } public ILInjector Back(int offset) { return Forward(-offset); } private void MarkInvalid() { index = -1; matchEnd = -1; } private void Search(bool forward, ILMatcher[] predicates) { if (!IsValid) { return; } int num = 1; if (!forward) { num = -1; index--; } while (forward ? (index < instructions.Count) : (index >= 0)) { if (forward && index + predicates.Length > instructions.Count) { index = instructions.Count; break; } int i; for (i = 0; i < predicates.Length && predicates[i].Matches(instructions[index + i]); i++) { } if (i == predicates.Length) { matchEnd = index + i; return; } index += num; } MarkInvalid(); } public ILInjector Find(params ILMatcher[] predicates) { Search(forward: true, predicates); return this; } public ILInjector ReverseFind(params ILMatcher[] predicates) { Search(forward: false, predicates); return this; } public ILInjector GoToPush(int popIndex) { if (!IsValid) { return this; } matchEnd = index; index--; int num = 0; while (index >= 0) { CodeInstruction instruction = instructions[index]; num += instruction.PushCount(); num -= instruction.PopCount(); if (num >= popIndex) { return this; } index--; } return this; } public ILInjector SkipBranch() { if (Instruction == null) { return this; } if (!(Instruction.operand is Label label)) { throw new InvalidOperationException($"Current instruction is not a branch: {Instruction}"); } return FindLabel(label); } public ILInjector FindLabel(Label label) { if (label == default(Label)) { return this; } matchEnd = index; for (index = 0; index < instructions.Count; index++) { if (instructions[index].labels.Contains(label)) { return this; } } MarkInvalid(); return this; } public ILInjector GoToMatchEnd() { index = matchEnd; return this; } public ILInjector GoToLastMatchedInstruction() { if (!IsIndexValid(matchEnd)) { return this; } index = matchEnd - 1; return this; } private bool IsIndexValid(int index) { return index != -1; } private bool IsIndexInRange(int index) { if (index >= 0) { return index < instructions.Count; } return false; } public CodeInstruction GetRelativeInstruction(int offset) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } int num = index + offset; if (!IsIndexInRange(num)) { throw new IndexOutOfRangeException($"Offset {offset} would read out of bounds at index {num}"); } return instructions[num]; } public ILInjector SetRelativeInstruction(int offset, CodeInstruction instruction) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } int num = index + offset; if (!IsIndexInRange(num)) { throw new IndexOutOfRangeException($"Offset {offset} would write out of bounds at index {num}"); } instructions[num] = instruction; return this; } [IteratorStateMachine(typeof(<GetRelativeInstructions>d__34))] public IEnumerable<CodeInstruction> GetRelativeInstructions(int offset, int size) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRelativeInstructions>d__34(-2) { <>4__this = this, <>3__offset = offset, <>3__size = size }; } public IEnumerable<CodeInstruction> GetRelativeInstructions(int size) { return GetRelativeInstructions(0, size); } private void GetLastMatchRangeAbsolute(out int start, out int end) { start = index; end = matchEnd; if (start > end) { int num = end; int num2 = start; start = num; end = num2; } } private void GetLastMatchRange(out int start, out int size) { GetLastMatchRangeAbsolute(out start, out var end); if (start < 0 || start >= instructions.Count) { throw new InvalidOperationException($"Last match range starts at invalid index {start}"); } if (end < 0 || end > instructions.Count) { throw new InvalidOperationException($"Last match range ends at invalid index {end}"); } size = end - start; } public List<CodeInstruction> GetLastMatch() { GetLastMatchRange(out var start, out var size); return instructions.GetRange(start, size); } public ILInjector DefineLabel(out Label label) { if (generator == null) { throw new InvalidOperationException("No ILGenerator was provided"); } label = generator.DefineLabel(); return this; } public ILInjector AddLabel(out Label label) { DefineLabel(out label); return AddLabel(label); } public ILInjector AddLabel(Label label) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Instruction = new CodeInstruction(Instruction); Instruction.labels.Add(label); return this; } public ILInjector InsertInPlace(params CodeInstruction[] instructions) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } this.instructions.InsertRange(index, instructions); if (matchEnd >= index) { matchEnd += instructions.Length; } return this; } public ILInjector Insert(params CodeInstruction[] instructions) { InsertInPlace(instructions); index += instructions.Length; return this; } public ILInjector InsertInPlaceAfterBranch(params CodeInstruction[] instructions) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } List<Label> labels = Instruction.labels; Instruction = new CodeInstruction(Instruction); Instruction.labels.Clear(); this.instructions.InsertRange(index, instructions); Instruction.labels.AddRange(labels); if (matchEnd >= index) { matchEnd += instructions.Length; } return this; } public ILInjector InsertAfterBranch(params CodeInstruction[] instructions) { InsertInPlaceAfterBranch(instructions); index += instructions.Length; return this; } public ILInjector RemoveAllPreviousInstructions() { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } instructions.RemoveRange(0, index); matchEnd -= index; if (matchEnd < 0) { matchEnd = 0; } index = 0; return this; } public ILInjector Remove(int count = 1) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } instructions.RemoveRange(index, count); if (matchEnd > index) { matchEnd = Math.Max(index, matchEnd - count); } return this; } public ILInjector RemoveLastMatch() { GetLastMatchRange(out var start, out var size); List<Label> labels = instructions[start].labels; instructions.RemoveRange(start, size); index = start; matchEnd = start; instructions[start].labels.AddRange(labels); return this; } public ILInjector ReplaceLastMatch(params CodeInstruction[] replacementInstructions) { if (replacementInstructions.Length == 0) { throw new ArgumentException("Cannot replace a match with an empty array."); } GetLastMatchRange(out var start, out var size); List<Label> labels = instructions[start].labels; instructions.RemoveRange(start, size); instructions.InsertRange(start, replacementInstructions); index = start; matchEnd = start + replacementInstructions.Length; instructions[start].labels.AddRange(labels); return this; } public List<CodeInstruction> ReleaseInstructions() { List<CodeInstruction> result = instructions; instructions = null; return result; } public ILInjector PrintContext(int context, string header = "") { if (!IsValid) { throw new InvalidOperationException("Injector is invalid (" + header + ")"); } StringBuilder stringBuilder = new StringBuilder(header); if (header.Length > 0) { stringBuilder.Append(':'); } stringBuilder.AppendLine(); GetLastMatchRangeAbsolute(out var start, out var end); int num = Math.Min(end + 1 + context, instructions.Count); for (int i = Math.Max(start - context, 0); i < num; i++) { if (end == -1 && i == index) { stringBuilder.Append("╶> "); } else { if (i >= start && i < end) { stringBuilder.Append("│"); } else { stringBuilder.Append(" "); } if (i == index) { stringBuilder.Append("╶> "); } else { stringBuilder.Append(" "); } } stringBuilder.AppendLine($"{i}: {instructions[i]}"); } EntranceTeleportOptimizations.Log.LogInfo((object)stringBuilder); return this; } public ILInjector PrintContext(string header = "") { return PrintContext(4, header); } } internal interface ILMatcher { bool Matches(CodeInstruction instruction); ILMatcher CaptureAs(out CodeInstruction variable) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown variable = new CodeInstruction(OpCodes.Nop, (object)null); return new InstructionCapturingMatcher(this, variable); } unsafe ILMatcher CaptureOperandAs<T>(out T operand) where T : unmanaged { operand = default(T); fixed (T* operand2 = &operand) { return new OperandCapturingMatcher<T>(this, operand2); } } ILMatcher Debug() { return new DebuggingMatcher(this); } static ILMatcher Not(ILMatcher matcher) { return new NotMatcher(matcher); } static ILMatcher Opcode(OpCode opcode) { return new OpcodeMatcher(opcode); } static ILMatcher Opcodes(params OpCode[] opcodes) { return new OpcodesMatcher(opcodes); } static ILMatcher OpcodeOperand(OpCode opcode, object operand) { return new OpcodeOperandMatcher(opcode, operand); } static ILMatcher Instruction(CodeInstruction instruction) { return new InstructionMatcher(instruction); } static ILMatcher Ldarg(int? arg = null) { return new LdargMatcher(arg); } static ILMatcher Ldloc(int? loc = null) { return new LdlocMatcher(loc); } static ILMatcher Stloc(int? loc = null) { return new StlocMatcher(loc); } static ILMatcher Ldc(int? value = null) { return new LdcI32Matcher(value); } static ILMatcher LdcF32(float? value = null) { return new LdcF32Matcher(value); } unsafe static ILMatcher LdlocCapture(out int localIndex) { localIndex = -1; fixed (int* localIndex2 = &localIndex) { return new LdlocCapturingMatcher(localIndex2); } } unsafe static ILMatcher Ldloc(in int localIndex) { fixed (int* localIndexPtr = &localIndex) { return new LdlocByRefMatcher(localIndexPtr); } } unsafe static ILMatcher StlocCapture(out int localIndex) { localIndex = -1; fixed (int* localIndex2 = &localIndex) { return new StlocCapturingMatcher(localIndex2); } } unsafe static ILMatcher Stloc(in int localIndex) { fixed (int* localIndexPtr = &localIndex) { return new StlocByRefMatcher(localIndexPtr); } } static ILMatcher Branch() { return new BranchMatcher(); } static ILMatcher Ldfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Field passed to ILMatcher.Ldfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Ldfld, field); } static ILMatcher Ldsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Field passed to ILMatcher.Ldsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Ldsfld, field); } static ILMatcher Stfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Field passed to ILMatcher.Stfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Stfld, field); } static ILMatcher Stsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Field passed to ILMatcher.Stsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Stsfld, field); } static ILMatcher Callvirt(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (method == null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Method passed to ILMatcher.Callvirt() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return OpcodeOperand(OpCodes.Callvirt, method); } static ILMatcher Call(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (method == null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Method passed to ILMatcher.Call() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return OpcodeOperand(OpCodes.Call, method); } static ILMatcher Predicate(Func<CodeInstruction, bool> predicate) { return new PredicateMatcher(predicate); } static ILMatcher Predicate(Func<FieldInfo, bool> predicate) { return new PredicateMatcher((CodeInstruction insn) => insn.operand is FieldInfo arg && predicate(arg)); } } internal class NotMatcher : ILMatcher { private readonly ILMatcher matcher; public NotMatcher(ILMatcher matcher) { this.matcher = matcher; base..ctor(); } public bool Matches(CodeInstruction instruction) { return !matcher.Matches(instruction); } } internal class OpcodeMatcher : ILMatcher { private readonly OpCode opcode; public OpcodeMatcher(OpCode opcode) { this.opcode = opcode; base..ctor(); } public bool Matches(CodeInstruction instruction) { return instruction.opcode == opcode; } } internal class OpcodesMatcher : ILMatcher { private readonly OpCode[] opcodes; public OpcodesMatcher(OpCode[] opcodes) { this.opcodes = opcodes; base..ctor(); } public bool Matches(CodeInstruction instruction) { return opcodes.Contains(instruction.opcode); } } internal class OpcodeOperandMatcher : ILMatcher { private readonly OpCode opcode; private readonly object operand; public OpcodeOperandMatcher(OpCode opcode, object operand) { this.opcode = opcode; this.operand = operand; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (instruction.opcode == opcode) { return instruction.operand == operand; } return false; } } internal class InstructionMatcher : ILMatcher { private readonly OpCode opcode = instruction.opcode; private readonly object operand = instruction.operand; private readonly Label[] labels = instruction.labels.ToArray(); public InstructionMatcher(CodeInstruction instruction) { } public bool Matches(CodeInstruction instruction) { if (instruction.opcode != opcode) { return false; } if (instruction.operand != operand) { return false; } if (instruction.labels.Count != labels.Length) { return false; } for (int i = 0; i < labels.Length; i++) { if (labels[i] != instruction.labels[i]) { return false; } } return true; } } internal class LdargMatcher : ILMatcher { private readonly int? arg; public LdargMatcher(int? arg) { this.arg = arg; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!arg.HasValue) { return instruction.GetLdargIndex().HasValue; } return instruction.GetLdargIndex() == arg; } } internal class LdlocMatcher : ILMatcher { private readonly int? loc; public LdlocMatcher(int? loc) { this.loc = loc; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!loc.HasValue) { return instruction.GetLdlocIndex().HasValue; } return instruction.GetLdlocIndex() == loc; } } internal class StlocMatcher : ILMatcher { private readonly int? loc; public StlocMatcher(int? loc) { this.loc = loc; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!loc.HasValue) { return instruction.GetStlocIndex().HasValue; } return instruction.GetStlocIndex() == loc; } } internal class LdcI32Matcher : ILMatcher { private readonly int? value; public LdcI32Matcher(int? value) { this.value = value; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!value.HasValue) { return instruction.GetLdcI32().HasValue; } return instruction.GetLdcI32() == value; } } internal class LdcF32Matcher : ILMatcher { private readonly float? value; public LdcF32Matcher(float? value) { this.value = value; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (instruction.opcode == OpCodes.Ldc_R4) { if (value.HasValue) { return (float)instruction.operand == value.Value; } return true; } return false; } } internal class BranchMatcher : ILMatcher { public bool Matches(CodeInstruction instruction) { Label? label = default(Label?); return CodeInstructionExtensions.Branches(instruction, ref label); } } internal class PredicateMatcher : ILMatcher { private readonly Func<CodeInstruction, bool> predicate; public PredicateMatcher(Func<CodeInstruction, bool> predicate) { this.predicate = predicate; base..ctor(); } public bool Matches(CodeInstruction instruction) { return predicate(instruction); } } internal class InstructionCapturingMatcher : ILMatcher { private readonly ILMatcher matcher; private readonly CodeInstruction variable; public InstructionCapturingMatcher(ILMatcher matcher, CodeInstruction variable) { this.matcher = matcher; this.variable = variable; base..ctor(); } public bool Matches(CodeInstruction instruction) { bool flag = matcher.Matches(instruction); if (flag) { variable.opcode = instruction.opcode; variable.operand = instruction.operand; variable.blocks = instruction.blocks.ToList(); variable.labels = instruction.labels.ToList(); } return flag; } } internal class OperandCapturingMatcher<T> : ILMatcher where T : unmanaged { private readonly ILMatcher matcher; private unsafe readonly T* operand; public unsafe OperandCapturingMatcher(ILMatcher matcher, T* operand) { this.matcher = matcher; this.operand = operand; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { bool flag = matcher.Matches(instruction); if (flag) { *operand = (T)instruction.operand; } return flag; } } internal class LdlocCapturingMatcher : ILMatcher { private unsafe readonly int* localIndex; public unsafe LdlocCapturingMatcher(int* localIndex) { this.localIndex = localIndex; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { int? ldlocIndex = instruction.GetLdlocIndex(); if (ldlocIndex.HasValue) { *localIndex = ldlocIndex.Value; return true; } return false; } } internal class LdlocByRefMatcher : ILMatcher { private unsafe readonly int* localIndexPtr; public unsafe LdlocByRefMatcher(int* localIndexPtr) { this.localIndexPtr = localIndexPtr; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { return instruction.GetLdlocIndex() == *localIndexPtr; } } internal class StlocCapturingMatcher : ILMatcher { private unsafe readonly int* localIndex; public unsafe StlocCapturingMatcher(int* localIndex) { this.localIndex = localIndex; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { int? stlocIndex = instruction.GetStlocIndex(); if (stlocIndex.HasValue) { *localIndex = stlocIndex.Value; return true; } return false; } } internal class StlocByRefMatcher : ILMatcher { private unsafe readonly int* localIndexPtr; public unsafe StlocByRefMatcher(int* localIndexPtr) { this.localIndexPtr = localIndexPtr; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { return instruction.GetStlocIndex() == *localIndexPtr; } } internal class DebuggingMatcher : ILMatcher { private readonly ILMatcher matcher; public DebuggingMatcher(ILMatcher matcher) { this.matcher = matcher; base..ctor(); } public bool Matches(CodeInstruction instruction) { bool flag = matcher.Matches(instruction); if (flag) { EntranceTeleportOptimizations.Log.LogInfo((object)$"{matcher} matched {instruction}"); } return flag; } } internal static class InstructionUtilities { public static CodeInstruction MakeLdarg(int index) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (index < 256) { return (CodeInstruction)(index switch { 0 => (object)new CodeInstruction(OpCodes.Ldarg_0, (object)null), 1 => (object)new CodeInstruction(OpCodes.Ldarg_1, (object)null), 2 => (object)new CodeInstruction(OpCodes.Ldarg_2, (object)null), 3 => (object)new CodeInstruction(OpCodes.Ldarg_3, (object)null), _ => (object)new CodeInstruction(OpCodes.Ldarg_S, (object)index), }); } return new CodeInstruction(OpCodes.Ldarg, (object)index); } public static int PopCount(this CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Newobj) { MethodBase methodBase = (MethodBase)instruction.operand; int num = methodBase.GetParameters().Length; if (!methodBase.IsStatic) { num++; } return num; } if (instruction.opcode == OpCodes.Ret) { return 1; } return instruction.opcode.StackBehaviourPop switch { StackBehaviour.Pop0 => 0, StackBehaviour.Pop1 => 1, StackBehaviour.Pop1_pop1 => 2, StackBehaviour.Popi => 1, StackBehaviour.Popi_pop1 => 2, StackBehaviour.Popi_popi => 2, StackBehaviour.Popi_popi8 => 2, StackBehaviour.Popi_popi_popi => 3, StackBehaviour.Popi_popr4 => 2, StackBehaviour.Popi_popr8 => 2, StackBehaviour.Popref => 1, StackBehaviour.Popref_pop1 => 2, StackBehaviour.Popref_popi => 2, StackBehaviour.Popref_popi_popi => 3, StackBehaviour.Popref_popi_popi8 => 3, StackBehaviour.Popref_popi_popr4 => 3, StackBehaviour.Popref_popi_popr8 => 3, StackBehaviour.Popref_popi_popref => 3, StackBehaviour.Varpop => throw new NotImplementedException($"Variable pop on non-call instruction '{instruction}'"), StackBehaviour.Popref_popi_pop1 => 3, _ => throw new NotSupportedException($"StackBehaviourPop of {instruction.opcode.StackBehaviourPop} was not a pop for instruction '{instruction}'"), }; } public static int PushCount(this CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Newobj) { if (instruction.operand is MethodInfo methodInfo && methodInfo.ReturnType == typeof(void)) { return 0; } return 1; } return instruction.opcode.StackBehaviourPush switch { StackBehaviour.Push0 => 0, StackBehaviour.Push1 => 1, StackBehaviour.Push1_push1 => 2, StackBehaviour.Pushi => 1, StackBehaviour.Pushi8 => 1, StackBehaviour.Pushr4 => 1, StackBehaviour.Pushr8 => 1, StackBehaviour.Pushref => 1, StackBehaviour.Varpush => throw new NotImplementedException($"Variable push on non-call instruction '{instruction}'"), _ => throw new NotSupportedException($"StackBehaviourPush of {instruction.opcode.StackBehaviourPush} was not a push for instruction '{instruction}'"), }; } public static int? GetLdargIndex(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldarg_0) { return 0; } if (opcode == OpCodes.Ldarg_1) { return 1; } if (opcode == OpCodes.Ldarg_2) { return 2; } if (opcode == OpCodes.Ldarg_3) { return 3; } if (opcode == OpCodes.Ldarg || opcode == OpCodes.Ldarg_S) { return instruction.operand as int?; } return null; } public static int? GetLdlocIndex(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldloc_0) { return 0; } if (opcode == OpCodes.Ldloc_1) { return 1; } if (opcode == OpCodes.Ldloc_2) { return 2; } if (opcode == OpCodes.Ldloc_3) { return 3; } if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S) { return (instruction.operand as LocalBuilder)?.LocalIndex; } return null; } public static int? GetStlocIndex(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Stloc_0) { return 0; } if (opcode == OpCodes.Stloc_1) { return 1; } if (opcode == OpCodes.Stloc_2) { return 2; } if (opcode == OpCodes.Stloc_3) { return 3; } if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S) { return (instruction.operand as LocalBuilder)?.LocalIndex; } return null; } public static CodeInstruction LdlocToStloc(this CodeInstruction instruction) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldloc_0) { return new CodeInstruction(OpCodes.Stloc_0, (object)null); } if (opcode == OpCodes.Ldloc_1) { return new CodeInstruction(OpCodes.Stloc_1, (object)null); } if (opcode == OpCodes.Ldloc_2) { return new CodeInstruction(OpCodes.Stloc_2, (object)null); } if (opcode == OpCodes.Ldloc_3) { return new CodeInstruction(OpCodes.Stloc_3, (object)null); } if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S) { return new CodeInstruction(OpCodes.Stloc, instruction.operand); } return null; } public static CodeInstruction StlocToLdloc(this CodeInstruction instruction) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown OpCode opcode = instruction.opcode; if (opcode == OpCodes.Stloc_0) { return new CodeInstruction(OpCodes.Ldloc_0, (object)null); } if (opcode == OpCodes.Stloc_1) { return new CodeInstruction(OpCodes.Ldloc_1, (object)null); } if (opcode == OpCodes.Stloc_2) { return new CodeInstruction(OpCodes.Ldloc_2, (object)null); } if (opcode == OpCodes.Stloc_3) { return new CodeInstruction(OpCodes.Ldloc_3, (object)null); } if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S) { return new CodeInstruction(OpCodes.Ldloc, instruction.operand); } return null; } public static int? GetLdcI32(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldc_I4_M1) { return -1; } if (opcode == OpCodes.Ldc_I4_0) { return 0; } if (opcode == OpCodes.Ldc_I4_1) { return 1; } if (opcode == OpCodes.Ldc_I4_2) { return 2; } if (opcode == OpCodes.Ldc_I4_3) { return 3; } if (opcode == OpCodes.Ldc_I4_4) { return 4; } if (opcode == OpCodes.Ldc_I4_5) { return 5; } if (opcode == OpCodes.Ldc_I4_6) { return 6; } if (opcode == OpCodes.Ldc_I4_7) { return 7; } if (opcode == OpCodes.Ldc_I4_8) { return 8; } if (opcode == OpCodes.Ldc_I4_S) { return instruction.operand as sbyte?; } if (opcode == OpCodes.Ldc_I4) { return instruction.operand as int?; } return null; } } public static class ReflectionExtensions { public static MethodInfo GetGenericMethod(this Type type, string name, Type[] parameters, Type[] genericArgs) { MethodInfo[] methods = type.GetMethods(); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (methodInfo.Name != name || !methodInfo.IsGenericMethodDefinition) { continue; } ParameterInfo[] parameters2 = methodInfo.GetParameters(); if (parameters.Length != parameters2.Length) { continue; } bool flag = true; for (int j = 0; j < parameters.Length; j++) { if (parameters[j] != parameters2[j].ParameterType) { flag = false; break; } } if (flag) { return methodInfo.MakeGenericMethod(genericArgs); } } return null; } } } namespace EntranceTeleportOptimizations.Patches { [HarmonyPatch] internal static class EntranceTeleportPatches { internal static readonly List<EntranceTeleport> TeleportList = new List<EntranceTeleport>(); internal static readonly Dictionary<EntranceTeleport, EntranceTeleport> TeleportMap = new Dictionary<EntranceTeleport, EntranceTeleport>(); internal static EntranceTeleport[] GetAllEntranceTeleports() { return NoAllocHelpers.ExtractArrayFromListT<EntranceTeleport>(TeleportList); } internal static IEnumerable<EntranceTeleport> GetValidEntranceTeleports() { return TeleportList.Where((EntranceTeleport t) => Object.op_Implicit((Object)(object)t) && ((Behaviour)t).isActiveAndEnabled); } internal static float GetEnemyDetectionRange(EntranceTeleport @this) { if (@this.isEntranceToBuilding) { return EntranceTeleportOptimizations.PluginConfig.InsideEnemyDetectionRangeConfig.Value; } return EntranceTeleportOptimizations.PluginConfig.OutsideEnemyDetectionRangeConfig.Value; } [HarmonyFinalizer] [HarmonyPatch(typeof(EntranceTeleport), "Awake")] private static void OnTeleportAwake(EntranceTeleport __instance) { TeleportList.Add(__instance); if (__instance.entranceId != 0 && !__instance.isEntranceToBuilding) { if (__instance.entranceId != 1) { EntranceTeleportOptimizations.Log.LogError((object)$"Found FireExit with id {__instance.entranceId}"); } if (EntranceTeleportOptimizations.PluginConfig.PatchPrefabIDsConfig.Value) { __instance.entranceId = 1; } } } [HarmonyFinalizer] [HarmonyPatch(typeof(NetworkBehaviour), "OnDestroy")] private static void OnTeleportDestroy(NetworkBehaviour __instance) { EntranceTeleport val = (EntranceTeleport)(object)((__instance is EntranceTeleport) ? __instance : null); if (val != null) { TeleportList.Remove(val); TeleportMap.Remove(val); } } [HarmonyPrefix] [HarmonyPriority(0)] [HarmonyPatch(typeof(EntranceTeleport), "FindExitPoint")] private static bool ReplaceFindExitPoint(EntranceTeleport __instance, ref bool __result, bool __runOriginal) { if (!__runOriginal) { EntranceTeleportOptimizations.Log.LogWarning((object)"Another mod is trying to suppress FindExitPoint!"); } if (Object.op_Implicit((Object)(object)__instance.exitScript)) { EntranceTeleport value; bool flag = TeleportMap.TryGetValue(__instance, out value); if (flag && Object.op_Implicit((Object)(object)value) && value.entranceId == __instance.entranceId) { __result = true; __instance.exitScript = value; return false; } if (!flag) { EntranceTeleportOptimizations.Log.LogWarning((object)$"exitPoint for {__instance} was set outside this mod!"); } else if (!Object.op_Implicit((Object)(object)value)) { EntranceTeleportOptimizations.Log.LogWarning((object)$"exitPoint for {__instance} was disabled or destroyed!"); } else { EntranceTeleportOptimizations.Log.LogWarning((object)$"{__instance} was using ID {value.entranceId} but now is {__instance.entranceId}!"); } } bool isEntranceToBuilding = __instance.isEntranceToBuilding; int entranceId = __instance.entranceId; __result = false; foreach (EntranceTeleport teleport in TeleportList) { if (Object.op_Implicit((Object)(object)teleport) && ((Behaviour)teleport).isActiveAndEnabled && teleport.isEntranceToBuilding != isEntranceToBuilding && teleport.entranceId == entranceId) { __instance.exitScript = teleport; __instance.gotExitPoint = true; TeleportMap[__instance] = teleport; __result = true; if (!__instance.isEntranceToBuilding && EntranceTeleportOptimizations.PluginConfig.RenameInteriorGameObjectsConfig.Value) { ((Object)((Component)__instance).gameObject).name = ((Object)((Component)teleport).gameObject).name + " (Interior)"; } return false; } } if (!__result) { TeleportMap.Remove(__instance); __instance.exitScript = null; __instance.gotExitPoint = false; } return false; } [HarmonyTranspiler] [HarmonyPatch(typeof(EntranceTeleport), "Update")] private static IEnumerable<CodeInstruction> PatchUpdate(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator, MethodBase method) { //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Expected O, but got Unknown //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Expected O, but got Unknown //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Expected O, but got Unknown //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Expected O, but got Unknown //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Expected O, but got Unknown //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Expected O, but got Unknown //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Expected O, but got Unknown //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_062b: Expected O, but got Unknown //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_0639: Expected O, but got Unknown //IL_0647: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Expected O, but got Unknown //IL_0766: Unknown result type (might be due to invalid IL or missing references) //IL_076c: Expected O, but got Unknown CodeInstruction[] array = instructions.ToArray(); MethodInfo method2 = typeof(Object).GetMethod("op_Equality", new Type[2] { typeof(Object), typeof(Object) }); ILInjector iLInjector = new ILInjector(array, ilGenerator); if (EntranceTeleportOptimizations.PluginConfig.DetectEnemyBothSidesConfig.Value) { iLInjector.Find(ILMatcher.Ldarg(), ILMatcher.Ldfld(typeof(EntranceTeleport).GetField("isEntranceToBuilding"), "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 168), ILMatcher.Branch(), ILMatcher.Opcode(OpCodes.Ret)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(30, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find the check for isEntranceToBuilding in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.RemoveLastMatch(); } iLInjector.Find(ILMatcher.Ldarg().CaptureAs(out var variable), ILMatcher.Ldfld(typeof(EntranceTeleport).GetField("gotExitPoint", BindingFlags.Instance | BindingFlags.NonPublic), "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 195), ILMatcher.Branch().CaptureOperandAs<Label>(out var operand)).FindLabel(operand); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(30, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find the check for gotExitPoint in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.RemoveLastMatch(); iLInjector.Find(ILMatcher.Ldarg(), ILMatcher.LdcF32(), ILMatcher.Stfld(typeof(EntranceTeleport).GetField("checkForEnemiesInterval", BindingFlags.Instance | BindingFlags.NonPublic), "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 218)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(30, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find store of checkForEnemiesInterval in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.GoToMatchEnd().AddLabel(out var label).Insert(variable, new CodeInstruction(OpCodes.Ldfld, (object)typeof(EntranceTeleport).GetField("exitScript")), new CodeInstruction(OpCodes.Ldnull, (object)null), new CodeInstruction(OpCodes.Call, (object)method2), new CodeInstruction(OpCodes.Brfalse, (object)label), new CodeInstruction(OpCodes.Ret, (object)null)); MethodInfo getMethod = typeof(RoundManager).GetProperty("Instance").GetMethod; FieldInfo field = typeof(RoundManager).GetField("SpawnedEnemies"); iLInjector.Find(ILMatcher.Ldloc(), ILMatcher.Call(getMethod, "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 254), ILMatcher.Ldfld(field, "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 255), ILMatcher.Callvirt(typeof(List<EnemyAI>).GetProperty("Count").GetMethod, "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 256), ILMatcher.Branch().CaptureOperandAs<Label>(out var operand2)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(30, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find start of enemies loop checkForEnemiesInterval in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.ReverseFind(ILMatcher.Ldloc(), ILMatcher.Ldc(), ILMatcher.Opcode(OpCodes.Add), ILMatcher.Stloc()); if (!iLInjector.IsValid) { iLInjector.GoToLastMatchedInstruction(); iLInjector.PrintContext(30, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find continue label of enemies loop checkForEnemiesInterval in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.AddLabel(out var label2).FindLabel(operand2); iLInjector.Find(ILMatcher.Call(getMethod, "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 289), ILMatcher.Ldfld(field, "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 290), ILMatcher.Ldloc(), ILMatcher.Callvirt(typeof(List<EnemyAI>).GetMethod("get_Item"), "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 292)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(30, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find enemy indexing checkForEnemiesInterval in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.GoToMatchEnd().DefineLabel(out var label3).Insert(new CodeInstruction(OpCodes.Dup, (object)null), new CodeInstruction(OpCodes.Ldnull, (object)null), new CodeInstruction(OpCodes.Call, (object)method2), new CodeInstruction(OpCodes.Brfalse, (object)label3), new CodeInstruction(OpCodes.Pop, (object)null), new CodeInstruction(OpCodes.Br, (object)label2)) .AddLabel(label3); iLInjector.Find(ILMatcher.Call(typeof(Vector3).GetMethod("Distance", new Type[2] { typeof(Vector3), typeof(Vector3) }), "PatchUpdate", "./Plugin/src/Patches/EntranceTeleportPatches.cs", 322).CaptureAs(out var variable2), ILMatcher.LdcF32(7.7f), ILMatcher.Branch().CaptureAs(out var variable3)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(40, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find call to Vector3.Distance in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.ReplaceLastMatch(variable2, variable, new CodeInstruction(OpCodes.Call, (object)typeof(EntranceTeleportPatches).GetMethod("GetEnemyDetectionRange", BindingFlags.Static | BindingFlags.NonPublic)), variable3); return iLInjector.ReleaseInstructions(); } } public static class MenuManagerPatches { [HarmonyFinalizer] [HarmonyPatch(typeof(MenuManager), "Awake")] private static void OnMainMenu() { EntranceTeleportPatches.TeleportMap.Clear(); EntranceTeleportPatches.TeleportList.Clear(); } } [HarmonyPatch] public static class RoundManagerPatches { [HarmonyTranspiler] [HarmonyPatch(typeof(RoundManager), "FindMainEntrancePosition")] [HarmonyPatch(typeof(RoundManager), "FindMainEntranceScript")] private static IEnumerable<CodeInstruction> ReplaceFindMainEntrancePosition(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator, MethodBase method) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Expected O, but got Unknown //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Expected O, but got Unknown //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Expected O, but got Unknown //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Expected O, but got Unknown //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Expected O, but got Unknown CodeInstruction[] array = instructions.ToArray(); CodeInstruction variable; ILInjector iLInjector = new ILInjector(array, ilGenerator).Find(ILMatcher.Ldc(), ILMatcher.Call(typeof(Object).GetGenericMethod("FindObjectsOfType", new Type[1] { typeof(bool) }, new Type[1] { typeof(EntranceTeleport) }), "ReplaceFindMainEntrancePosition", "./Plugin/src/Patches/RoundManagerPatches.cs", 29), ILMatcher.Stloc().CaptureAs(out variable)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(15, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find the call to get all entrance teleports in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.ReplaceLastMatch(new CodeInstruction(OpCodes.Call, (object)typeof(EntranceTeleportPatches).GetMethod("GetAllEntranceTeleports", BindingFlags.Static | BindingFlags.NonPublic)), variable); iLInjector.Find(ILMatcher.Opcode(OpCodes.Br).CaptureOperandAs<Label>(out var operand)).FindLabel(operand).Find(ILMatcher.Ldloc().CaptureAs(out var variable2), ILMatcher.Ldloc(variable.GetStlocIndex()), ILMatcher.Opcode(OpCodes.Ldlen), ILMatcher.Opcode(OpCodes.Conv_I4)); if (!iLInjector.IsValid) { EntranceTeleportOptimizations.Log.LogError((object)("Failed to find the call to teleports.Length in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.ReplaceLastMatch(variable2.Clone(), new CodeInstruction(OpCodes.Ldsfld, (object)typeof(EntranceTeleportPatches).GetField("TeleportList", BindingFlags.Static | BindingFlags.NonPublic)), new CodeInstruction(OpCodes.Call, (object)typeof(List<EntranceTeleport>).GetProperty("Count").GetMethod)).Find(ILMatcher.Branch().CaptureOperandAs<Label>(out var operand2)).FindLabel(operand2); if (!iLInjector.IsValid) { EntranceTeleportOptimizations.Log.LogError((object)("Failed to find start of loop in " + method.DeclaringType.Name + "." + method.Name)); return array; } CodeInstruction val = variable.StlocToLdloc(); iLInjector.InsertAfterBranch(val.Clone(), variable2.Clone(), new CodeInstruction(OpCodes.Ldelem_Ref, (object)null), new CodeInstruction(OpCodes.Ldnull, (object)null), new CodeInstruction(OpCodes.Call, (object)typeof(Object).GetMethod("op_Equality", new Type[2] { typeof(Object), typeof(Object) })), new CodeInstruction(OpCodes.Brtrue, (object)operand)).Insert(val.Clone(), variable2.Clone(), new CodeInstruction(OpCodes.Ldelem_Ref, (object)null), new CodeInstruction(OpCodes.Call, (object)typeof(Behaviour).GetProperty("isActiveAndEnabled").GetMethod), new CodeInstruction(OpCodes.Brfalse, (object)operand)); return iLInjector.ReleaseInstructions(); } [HarmonyTranspiler] [HarmonyPatch(typeof(RoundManager), "SetExitIDs")] private static IEnumerable<CodeInstruction> PatchSetExitIDs(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator, MethodBase method) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown CodeInstruction[] array = instructions.ToArray(); CodeInstruction variable; CodeInstruction variable2; ILInjector iLInjector = new ILInjector(array, ilGenerator).Find(ILMatcher.Stloc().CaptureAs(out variable), ILMatcher.Call(typeof(Object).GetGenericMethod("FindObjectsOfType", Array.Empty<Type>(), new Type[1] { typeof(EntranceTeleport) }), "PatchSetExitIDs", "./Plugin/src/Patches/RoundManagerPatches.cs", 132), ILMatcher.Ldloc().CaptureAs(out variable2)); if (!iLInjector.IsValid) { iLInjector.GoToStart(); iLInjector.PrintContext(15, method.DeclaringType.Name + "." + method.Name); EntranceTeleportOptimizations.Log.LogError((object)("Failed to find the call to get all entrance teleports in " + method.DeclaringType.Name + "." + method.Name)); return array; } iLInjector.ReplaceLastMatch(variable, new CodeInstruction(OpCodes.Call, (object)typeof(EntranceTeleportPatches).GetMethod("GetValidEntranceTeleports", BindingFlags.Static | BindingFlags.NonPublic)), variable2); return iLInjector.ReleaseInstructions(); } [HarmonyFinalizer] [HarmonyPatch(typeof(RoundManager), "SetExitIDs")] private static void OnDungeonReady() { //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) Dictionary<int, (EntranceTeleport, EntranceTeleport)> dictionary = default(Dictionary<int, (EntranceTeleport, EntranceTeleport)>); PooledObject<Dictionary<int, (EntranceTeleport, EntranceTeleport)>> val = CollectionPool<Dictionary<int, (EntranceTeleport, EntranceTeleport)>, KeyValuePair<int, (EntranceTeleport, EntranceTeleport)>>.Get(ref dictionary); try { foreach (EntranceTeleport teleport in EntranceTeleportPatches.TeleportList) { if (!Object.op_Implicit((Object)(object)teleport)) { continue; } EntranceTeleportPatches.TeleportMap.Remove(teleport); teleport.exitScript = null; teleport.gotExitPoint = false; if (!((Behaviour)teleport).isActiveAndEnabled) { continue; } int entranceId = teleport.entranceId; if (!dictionary.TryGetValue(entranceId, out var value)) { value = default((EntranceTeleport, EntranceTeleport)); } if (teleport.isEntranceToBuilding) { if ((Object)(object)value.Item1 != (Object)null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Found duplicated entrance for id: {entranceId}!"); } else { value.Item1 = teleport; } } else if ((Object)(object)value.Item2 != (Object)null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Found duplicated exit for id: {entranceId}!"); } else { value.Item2 = teleport; } dictionary[entranceId] = value; } foreach (KeyValuePair<int, (EntranceTeleport, EntranceTeleport)> item in dictionary) { item.Deconstruct(out var key, out var value2); (EntranceTeleport, EntranceTeleport) tuple = value2; int num = key; var (val2, val3) = tuple; if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { EntranceTeleportOptimizations.Log.LogWarning((object)$"Found Missing Teleport for id: {num}!"); continue; } EntranceTeleportPatches.TeleportMap[val2] = val3; val2.exitScript = val3; val2.gotExitPoint = true; val2.FindExitPoint(); EntranceTeleportPatches.TeleportMap[val3] = val2; val3.exitScript = val2; val3.gotExitPoint = true; val3.FindExitPoint(); if (EntranceTeleportOptimizations.PluginConfig.RenameInteriorGameObjectsConfig.Value) { ((Object)((Component)val3).gameObject).name = ((Object)((Component)val2).gameObject).name + " (Interior)"; } } EntranceTeleportOptimizations.Log.LogWarning((object)$"Connected {EntranceTeleportPatches.TeleportMap.Count} teleports"); } finally { ((IDisposable)val).Dispose(); } } } [HarmonyPatch] internal static class UnityObjectPatch { [StructLayout(LayoutKind.Sequential, Size = 1)] private readonly struct InstanceComparer : IComparer<Object> { internal static readonly InstanceComparer INSTANCE; public int Compare(Object x, Object y) { if (y == null) { return 1; } if (x == null) { return -1; } return x.GetInstanceID().CompareTo(y.GetInstanceID()); } } [HarmonyPrefix] [HarmonyBefore(new string[] { "LethalPerformance" })] [HarmonyPatch(typeof(Object), "FindObjectsByType", new Type[] { typeof(Type), typeof(FindObjectsInactive), typeof(FindObjectsSortMode) })] private static bool FindObjectsByTypeRedirect(bool __runOriginal, Type type, FindObjectsInactive findObjectsInactive, FindObjectsSortMode sortMode, ref Object[] __result) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_0023: 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_0028: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (!__runOriginal) { return false; } if (type != typeof(EntranceTeleport)) { return true; } EntranceTeleport[] filteredTeleports = GetFilteredTeleports((int)findObjectsInactive > 0); Object[] array; if ((int)sortMode != 0) { if ((int)sortMode != 1) { throw new ArgumentOutOfRangeException("sortMode", sortMode, null); } array = (Object[])(object)filteredTeleports; Array.Sort(array, InstanceComparer.INSTANCE); } array = (Object[])(object)filteredTeleports; __result = array; return false; } [HarmonyPrefix] [HarmonyBefore(new string[] { "LethalPerformance" })] [HarmonyPatch(typeof(Object), "FindObjectsOfType", new Type[] { typeof(Type), typeof(bool) })] private static bool FindObjectsOfTypeRedirect(bool __runOriginal, Type type, bool includeInactive, ref Object[] __result) { if (!__runOriginal) { return false; } if (type != typeof(EntranceTeleport)) { return true; } Object[] filteredTeleports = (Object[])(object)GetFilteredTeleports(includeInactive); __result = filteredTeleports; return false; } private static EntranceTeleport[] GetFilteredTeleports(bool includeInactive) { //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) List<EntranceTeleport> list = default(List<EntranceTeleport>); PooledObject<List<EntranceTeleport>> val = CollectionPool<List<EntranceTeleport>, EntranceTeleport>.Get(ref list); try { foreach (EntranceTeleport teleport in EntranceTeleportPatches.TeleportList) { if (!((Object)(object)teleport == (Object)null) && (includeInactive || ((Behaviour)teleport).isActiveAndEnabled)) { list.Add(teleport); } } return list.ToArray(); } finally { ((IDisposable)val).Dispose(); } } } } namespace EntranceTeleportOptimizations.Dependency { public static class LethalConfigProxy { [Serializable] [CompilerGenerated] private sealed class <>c__7<T> where T : Enum { public static readonly <>c__7<T> <>9 = new <>c__7<T>(); public static CanModifyDelegate <>9__7_0; public static CanModifyDelegate <>9__7_1; internal CanModifyResult <AddConfig>b__7_0() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return CanModifyResult.op_Implicit((ValueTuple<bool, string>)(true, null)); } internal CanModifyResult <AddConfig>b__7_1() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return CanModifyResult.op_Implicit((false, "THIS IS A FLAG TYPE ENUM, EDITING CURRENTLY NOT SUPPORTED!")); } } private static bool? _enabled; public static bool Enabled { get { bool valueOrDefault = _enabled.GetValueOrDefault(); if (!_enabled.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"); _enabled = valueOrDefault; } return _enabled.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig(ConfigEntry<string> entry, bool requiresRestart = false) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(entry, new TextInputFieldOptions { RequiresRestart = requiresRestart, Name = GetPrettyConfigName<string>(entry) })); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig(ConfigEntry<bool> entry, bool requiresRestart = false) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(entry, new BoolCheckBoxOptions { RequiresRestart = requiresRestart, Name = GetPrettyConfigName<bool>(entry) })); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig(ConfigEntry<float> entry, bool requiresRestart = false) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(entry, new FloatInputFieldOptions { RequiresRestart = requiresRestart, Name = GetPrettyConfigName<float>(entry) })); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig(ConfigEntry<int> entry, bool requiresRestart = false) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(entry, new IntInputFieldOptions { RequiresRestart = requiresRestart, Name = GetPrettyConfigName<int>(entry) })); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig<T>(ConfigEntry<T> entry, bool requiresRestart = false) where T : Enum { //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 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown object obj = <>c__7<T>.<>9__7_0; if (obj == null) { CanModifyDelegate val = () => CanModifyResult.op_Implicit((ValueTuple<bool, string>)(true, null)); <>c__7<T>.<>9__7_0 = val; obj = (object)val; } CanModifyDelegate canModifyCallback = (CanModifyDelegate)obj; if (((ConfigEntryBase)entry).SettingType.GetCustomAttributes(typeof(FlagsAttribute), inherit: true).Any()) { object obj2 = <>c__7<T>.<>9__7_1; if (obj2 == null) { CanModifyDelegate val2 = () => CanModifyResult.op_Implicit((false, "THIS IS A FLAG TYPE ENUM, EDITING CURRENTLY NOT SUPPORTED!")); <>c__7<T>.<>9__7_1 = val2; obj2 = (object)val2; } canModifyCallback = (CanModifyDelegate)obj2; } LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem<T>(entry, new EnumDropDownOptions { RequiresRestart = requiresRestart, CanModifyCallback = canModifyCallback })); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddButton(string section, string name, string description, string buttonText, Action callback) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate { callback?.Invoke(); })); } private static string GetPrettyConfigName<T>(ConfigEntry<T> entry) { return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(((ConfigEntryBase)entry).Definition.Key.Replace("_", " ")); } } public static class LobbyCompatibilityChecker { private static bool? _enabled; public static bool Enabled { get { bool valueOrDefault = _enabled.GetValueOrDefault(); if (!_enabled.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"); _enabled = valueOrDefault; } return _enabled.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void Init() { PluginHelper.RegisterPlugin("mattymatty.EntranceTeleportOptimizations", Version.Parse("1.0.0"), (CompatibilityLevel)2, (VersionStrictness)2); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }