using System; using System.Collections; using System.Collections.Concurrent; 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.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using HarmonyLib.Public.Patching; using JetBrains.Annotations; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using LobbyControl.API; using LobbyControl.Dependency; using LobbyControl.Networking; using LobbyControl.Patches; using LobbyControl.PopUp; using LobbyControl.TerminalCommands; using LobbyControl.Utils; using LobbyControl.Utils.IL; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.RuntimeDetour; using MonoMod.Utils; using Netcode.Transports.Facepunch; using Steamworks; using Steamworks.Data; using TMPro; using Unity.Collections; using Unity.Netcode; using Unity.Netcode.Transports.UTP; using Unity.Networking.Transport; using UnityEngine; using UnityEngine.Pool; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [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("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: AssemblyCompany("mattymatty")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.5.12")] [assembly: AssemblyInformationalVersion("2.5.12+71c015f4c339daeda77c450162c119fd8080f7dd")] [assembly: AssemblyProduct("LobbyControl")] [assembly: AssemblyTitle("LobbyControl - Plugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.5.12.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [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 LobbyControl { [BepInPlugin("mattymatty.LobbyControl", "LobbyControl", "2.5.12")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class LobbyControl : BaseUnityPlugin { public const string GUID = "mattymatty.LobbyControl"; public const string NAME = "LobbyControl"; public const string VERSION = "2.5.12"; public static LobbyControl Instance; internal static ManualLogSource Log; public static bool CanModifyLobby = true; public static bool CanSave = true; public static bool AutoSaveEnabled = true; private static readonly string[] IncompatibleGUIDs = new string[4] { "com.github.tinyhoot.ShipLobby", "twig.latecompany", "McBowie.VeryLateCompany", "com.potatoepet.AdvancedCompany" }; internal static readonly List FoundIncompatibilities = new List(); internal static Harmony Harmony { get; private set; } internal static HashSet Hooks { get; } = new HashSet(); private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; try { Harmony = new Harmony("mattymatty.LobbyControl"); PluginInfo[] array = Chainloader.PluginInfos.Values.Where((PluginInfo p) => IncompatibleGUIDs.Contains(p.Metadata.GUID)).ToArray(); if (array.Length != 0) { StringBuilder stringBuilder = new StringBuilder("LOBBY CONTROL was DISABLED!\nIncompatible:"); FoundIncompatibilities.AddRange(array); PluginInfo[] array2 = array; foreach (PluginInfo val in array2) { Log.LogWarning((object)(val.Metadata.Name + " is incompatible!")); stringBuilder.Append("\n").Append(val.Metadata.Name); } Log.LogError((object)$"{array.Length} incompatible mods found! Disabling!"); PopUpPatch.PopUps.Add(("LC_Incompatibility", stringBuilder.ToString())); Harmony.PatchAll(typeof(PopUpPatch)); return; } if (LobbyCompatibilityChecker.Enabled) { LobbyCompatibilityChecker.Init("mattymatty.LobbyControl", Version.Parse("2.5.12"), 1, 2); } Log.LogInfo((object)"Initializing Configs"); PluginConfig.Init((BaseUnityPlugin)(object)this); CommandManager.Initialize(); LobbyCommand.Init(); Log.LogInfo((object)"Patching Methods"); Harmony.PatchAll(typeof(PopUpPatch)); Harmony.PatchAll(typeof(FacepunchTransportPatches)); Harmony.PatchAll(typeof(JoinQueuePatches)); JoinQueuePatches.Init(); Harmony.PatchAll(typeof(LateJoinPatches)); Harmony.PatchAll(typeof(LimitPatcher)); Harmony.PatchAll(typeof(LobbyPatcher)); Harmony.PatchAll(typeof(LogSpamPatches)); Harmony.PatchAll(typeof(NetworkManagerPatch)); Harmony.PatchAll(typeof(SavePatches)); Harmony.PatchAll(typeof(TerminalPatch)); Log.LogInfo((object)"LobbyControl v2.5.12 Loaded!"); } catch (Exception ex) { Log.LogError((object)("Exception while initializing: \n" + ex)); } } } internal static class PluginConfig { internal static class SteamLobby { internal static ConfigEntry AutoLobby; } internal static class SaveLimit { internal static ConfigEntry Enabled; } internal static class LogSpam { internal static ConfigEntry Enabled; internal static ConfigEntry CalculatePolygonPath; } internal static class JoinQueue { internal static ConfigEntry Enabled; internal static ConfigEntry MaxSize; internal static ConfigEntry ConnectionTimeout; internal static ConfigEntry TimeoutPopup; internal static ConfigEntry ConnectionPopup; internal static ConfigEntry PreLobbyChannel; } internal static class Networking { internal static ConfigEntry Enabled; internal static ConfigEntry SyncRadarNames; internal static ConfigEntry ResetPlayerValues; } internal static void Init(BaseUnityPlugin plugin) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown ConfigFile config = plugin.Config; config.SaveOnConfigSet = false; SaveLimit.Enabled = config.Bind("SaveLimit", "enabled", true, "remove the limit to the amount of items that can be saved"); SteamLobby.AutoLobby = config.Bind("SteamLobby", "auto_lobby", false, "automatically reopen the lobby as soon as you reach orbit"); LogSpam.Enabled = config.Bind("LogSpam", "enabled", true, "prevent some annoying log spam"); LogSpam.CalculatePolygonPath = config.Bind("LogSpam", "CalculatePolygonPath", true, "stop pathfinding for dead Enemies"); JoinQueue.Enabled = config.Bind("JoinQueue", "enabled", true, "handle joining players as a queue instead of at the same time"); JoinQueue.MaxSize = config.Bind("JoinQueue", "max_size", 3, new ConfigDescription("max number of players in queue ( if queue is full extra connections will be refused )", (AcceptableValueBase)(object)new AcceptableValueRange(1, 65535), Array.Empty())); JoinQueue.ConnectionTimeout = config.Bind("JoinQueue", "connection_timeout_ms", 40000, new ConfigDescription("After how much time discard a hanging connection", (AcceptableValueBase)(object)new AcceptableValueRange(10000, int.MaxValue), Array.Empty())); JoinQueue.TimeoutPopup = config.Bind("JoinQueue", "timeout_notification", true, "show a popup when a client fails to join before the timeout"); JoinQueue.ConnectionPopup = config.Bind("JoinQueue", "connection_notification", false, "show a popup when a client tries to join"); JoinQueue.PreLobbyChannel = config.Bind("JoinQueue", "pre-lobby_channel", 28, new ConfigDescription("channel to use for pre-lobby connections", (AcceptableValueBase)(object)new AcceptableValueRange(1, 255), Array.Empty())); Networking.Enabled = config.Bind("Networking", "enabled", true, "handle extra actions requested by host"); Networking.SyncRadarNames = config.Bind("Networking", "sync_radar_names", false, "allow host to reorder radar names to align clients\nWARNING: all clients need to have the mod installed or desyncs might will happen"); Networking.ResetPlayerValues = config.Bind("Networking", "reset_player_values", true, "allow host to force clients to reset most fields of a playerObject ( fix for invisible players )"); JoinQueue.ConnectionTimeout.SettingChanged += delegate { NetworkManager singleton = NetworkManager.Singleton; if (singleton != null) { singleton.NetworkConfig.ClientConnectionBufferTimeout = JoinQueue.ConnectionTimeout.Value / 1000 * 4; } }; if (LethalConfigProxy.Enabled) { LethalConfigProxy.AddConfig(SaveLimit.Enabled); LethalConfigProxy.AddConfig(SteamLobby.AutoLobby); LethalConfigProxy.AddConfig(LogSpam.Enabled); LethalConfigProxy.AddConfig(LogSpam.CalculatePolygonPath); LethalConfigProxy.AddConfig(JoinQueue.Enabled); LethalConfigProxy.AddConfig(JoinQueue.MaxSize); LethalConfigProxy.AddConfig(JoinQueue.ConnectionTimeout); LethalConfigProxy.AddConfig(JoinQueue.TimeoutPopup); LethalConfigProxy.AddConfig(JoinQueue.ConnectionPopup); LethalConfigProxy.AddConfig(JoinQueue.PreLobbyChannel); LethalConfigProxy.AddConfig(Networking.Enabled); LethalConfigProxy.AddConfig(Networking.SyncRadarNames); LethalConfigProxy.AddConfig(Networking.ResetPlayerValues); } PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary dictionary = (Dictionary)property.GetValue(config, null); dictionary.Clear(); config.Save(); config.SaveOnConfigSet = true; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "mattymatty.LobbyControl"; public const string PLUGIN_NAME = "LobbyControl"; public const string PLUGIN_VERSION = "2.5.12"; } } namespace LobbyControl.Utils { public class FreeRunningTimer { private readonly Stopwatch _stopwatch = new Stopwatch(); private TimeSpan _timeout = TimeSpan.Zero; public bool Enabled => _stopwatch.IsRunning; public bool TimedOut => _stopwatch.Elapsed > _timeout; public TimeSpan Elapsed => _stopwatch.Elapsed; public TimeSpan Remaining { get { if (!TimedOut) { return _timeout - _stopwatch.Elapsed; } return TimeSpan.Zero; } } public void Start(TimeSpan timeout) { _timeout = timeout; _stopwatch.Restart(); } public void Stop() { _stopwatch.Stop(); } } public static class HudUtils { private static readonly WaitUntil WaitForAnimation = new WaitUntil((Func)delegate { //IL_000b: 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) AnimatorStateInfo currentAnimatorStateInfo = HUDManager.Instance.tipsPanelAnimator.GetCurrentAnimatorStateInfo(0); return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f; }); internal static IEnumerator ShowMessageAfterDelay(string title, string text, float delay = 0f, bool isWarning = false) { if (delay > 0f) { yield return (object)new WaitForSeconds(delay); } yield return WaitForAnimation; HUDManager.Instance.DisplayTip(title, text, isWarning, false, "LC_Tip1"); } internal static IEnumerator ShowTipAfterDelay(string title, string text, float delay, string saveKey) { if (delay > 0f) { yield return (object)new WaitForSeconds(delay); } yield return WaitForAnimation; HUDManager.Instance.DisplayTip(title, text, false, true, saveKey); } } public static class RPCUtils { private static readonly MethodInfo BeginSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendClientRpc", (Type[])null, (Type[])null); private static readonly MethodInfo BeginSendServerRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendServerRpc", (Type[])null, (Type[])null); internal static bool TryGetRpcID(MethodInfo methodInfo, out uint rpcID) { //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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_004b: Unknown result type (might be due to invalid IL or missing references) Collection instructions = PatchManager.GetMethodPatcher((MethodBase)methodInfo).CopyOriginal().Definition.Body.Instructions; rpcID = 0u; for (int i = 0; i < instructions.Count; i++) { if (instructions[i].OpCode == OpCodes.Ldc_I4 && instructions[i - 1].OpCode == OpCodes.Ldarg_0) { rpcID = (uint)(int)instructions[i].Operand; } if (!(instructions[i].OpCode != OpCodes.Call)) { object operand = instructions[i].Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && (Extensions.Is((MemberReference)(object)val, (MemberInfo)BeginSendClientRpc) || Extensions.Is((MemberReference)(object)val, (MemberInfo)BeginSendServerRpc))) { LobbyControl.Log.LogDebug((object)$"Rpc Id found for {methodInfo.Name}: {rpcID}U"); return true; } } } LobbyControl.Log.LogFatal((object)("Cannot find Rpc ID for " + methodInfo.Name)); return false; } } } namespace LobbyControl.Utils.IL { internal class ILInjector { private const string INVALID = "Injector is invalid"; private List 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 Instructions => instructions.AsReadOnly(); public ILInjector(IEnumerable 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; } public IEnumerable GetRelativeInstructions(int offset, int size) { for (int i = 0; i < size; i++) { yield return instructions[index + offset + i]; } } public IEnumerable 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 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