Decompiled source of LobbyControl Experimental v4.10.0
LobbyControl/LobbyControl.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using HarmonyLib.Public.Patching; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using LobbyControl.Dependency; using LobbyControl.Patches; using LobbyControl.PopUp; using LobbyControl.TerminalCommands; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.RuntimeDetour; using MonoMod.Utils; using ReservedItemSlotCore.Data; using Steamworks; using Steamworks.Data; using TMPro; using Unity.Collections; using Unity.Netcode; using Unity.Netcode.Transports.UTP; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: AssemblyCompany("LobbyControl")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.4.10.0")] [assembly: AssemblyInformationalVersion("2.4.10+524a6bbccbe0290d5d26eb023d0ae9bda3efd4eb")] [assembly: AssemblyProduct("Lobby Control")] [assembly: AssemblyTitle("LobbyControl")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.4.10.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] [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.4.10")] [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 { internal static class PluginConfig { internal static class SteamLobby { internal static ConfigEntry<bool> AutoLobby; internal static ConfigEntry<bool> RadarFix; } internal static class ItemSync { internal static ConfigEntry<bool> GhostItems; internal static ConfigEntry<bool> ForceDrop; internal static ConfigEntry<bool> ShotGunReload; internal static ConfigEntry<bool> SyncOnUse; internal static ConfigEntry<bool> SyncOnInteract; internal static ConfigEntry<string> SyncIgnoreName; } internal static class SaveLimit { internal static ConfigEntry<bool> Enabled; } internal static class InvisiblePlayer { internal static ConfigEntry<bool> Enabled; } internal static class LogSpam { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> CalculatePolygonPath; internal static ConfigEntry<bool> AudioSpatializer; } internal static class JoinQueue { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> ConnectionTimeout; internal static ConfigEntry<int> ConnectionDelay; } internal static void Init(BaseUnityPlugin plugin) { ConfigFile config = plugin.Config; ItemSync.GhostItems = config.Bind<bool>("ItemSync", "ghost_items", true, "prevent the creation of non-grabbable items in case of inventory desync"); ItemSync.ForceDrop = config.Bind<bool>("ItemSync", "force_drop", true, "forcefully drop all items of the player causing the desync"); ItemSync.ShotGunReload = config.Bind<bool>("ItemSync", "shotgun_reload", true, "prevent the shotgun disappearing when reloading it"); ItemSync.SyncOnUse = config.Bind<bool>("ItemSync", "sync_on_use", false, "sync held object upon usage"); ItemSync.SyncOnInteract = config.Bind<bool>("ItemSync", "sync_on_interact", false, "sync held object upon interaction"); ItemSync.SyncIgnoreName = config.Bind<string>("ItemSync", "sync_ignore_name", "Flashlight,Pro-flashlight,Laser pointer", "do not attempt sync on items that are in the list (compatibility with FlashLight toggle, ecc)"); SaveLimit.Enabled = config.Bind<bool>("SaveLimit", "enabled", true, "remove the limit to the amount of items that can be saved"); InvisiblePlayer.Enabled = config.Bind<bool>("InvisiblePlayer", "enabled", true, "attempts to fix late joining players appearing invisible to the rest of the lobby"); SteamLobby.AutoLobby = config.Bind<bool>("SteamLobby", "auto_lobby", false, "automatically reopen the lobby as soon as you reach orbit"); SteamLobby.RadarFix = config.Bind<bool>("SteamLobby", "radar_fix", true, "fix mismatched radar names if a radar booster was activated during the play session"); LogSpam.Enabled = config.Bind<bool>("LogSpam", "enabled", true, "prevent some annoying log spam"); LogSpam.CalculatePolygonPath = config.Bind<bool>("LogSpam", "CalculatePolygonPath", true, "stop pathfinding for dead Enemies"); LogSpam.AudioSpatializer = config.Bind<bool>("LogSpam", "audio_spatializer", true, "disable audio spatialization as there is not spatialization plugin"); JoinQueue.Enabled = config.Bind<bool>("JoinQueue", "enabled", true, "handle joining players as a queue instead of at the same time"); JoinQueue.ConnectionTimeout = config.Bind<int>("JoinQueue", "connection_timeout_ms", 3000, "After how much time discard a hanging connection"); JoinQueue.ConnectionDelay = config.Bind<int>("JoinQueue", "connection_delay_ms", 500, "Delay between each successful connection"); PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null); dictionary.Clear(); config.Save(); } } public const string GUID = "mattymatty.LobbyControl"; public const string NAME = "LobbyControl"; public const string VERSION = "2.4.10"; internal static ManualLogSource Log; internal static Harmony _harmony; public static bool CanModifyLobby = true; public static bool CanSave = true; public static bool AutoSaveEnabled = true; public static readonly List<Hook> Hooks = new List<Hook>(); private static readonly string[] IncompatibleGUIDs = new string[3] { "com.github.tinyhoot.ShipLobby", "twig.latecompany", "com.potatoepet.AdvancedCompany" }; internal static readonly List<PluginInfo> FoundIncompatibilities = new List<PluginInfo>(); private void Awake() { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { 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!"); Harmony val2 = new Harmony("mattymatty.LobbyControl"); PopUpPatch.PopUps.Add(new Tuple<string, string>("LC_Incompatibility", stringBuilder.ToString())); val2.PatchAll(typeof(PopUpPatch)); } else { if (LobbyCompatibilityChecker.Enabled) { LobbyCompatibilityChecker.Init("mattymatty.LobbyControl", Version.Parse("2.4.10"), 1, 2); } Log.LogInfo((object)"Initializing Configs"); PluginConfig.Init((BaseUnityPlugin)(object)this); CommandManager.Initialize(); Log.LogInfo((object)"Patching Methods"); _harmony = new Harmony("mattymatty.LobbyControl"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); JoinPatches.Init(); TransparentPlayerFix.Init(); Log.LogInfo((object)"LobbyControl v2.4.10 Loaded!"); } } catch (Exception ex) { Log.LogError((object)("Exception while initializing: \n" + ex)); } } } public static class Utils { 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<Instruction> 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.TerminalCommands { public class Command { public TerminalNode previousTerminalNode; public bool awaitingConfirmation { get { return CommandManager.awaitingConfirmationCommand == this; } set { CommandManager.awaitingConfirmationCommand = (value ? this : null); } } public virtual bool IsCommand(string[] args) { return false; } public virtual TerminalNode Execute(string[] args) { return TerminalPatch.CreateTerminalNode("Execute override was not found.\n\n"); } public virtual TerminalNode ExecuteConfirmation(string[] args) { string text = args[0].ToLower(); if ("confirm".Contains(text) && text.Length > 0) { return OnConfirm(args); } if ("deny".Contains(text) && text.Length > 0) { return OnDeny(args); } return OnInvalidInput(args); } protected virtual TerminalNode OnConfirm(string[] args) { return TerminalPatch.CreateTerminalNode("OnConfirm override was not found.\n\n"); } protected virtual TerminalNode OnDeny(string[] args) { return TerminalPatch.CreateTerminalNode("OnDeny override was not found.\n\n"); } protected virtual TerminalNode OnInvalidInput(string[] args) { return previousTerminalNode; } } internal class CommandManager { private static List<Command> commands = new List<Command>(); public static Command awaitingConfirmationCommand; public static void Initialize() { commands = new List<Command> { new LobbyCommand() }; awaitingConfirmationCommand = null; } public static bool TryExecuteCommand(string[] array, out TerminalNode terminalNode) { terminalNode = null; if (awaitingConfirmationCommand != null) { Command command = awaitingConfirmationCommand; terminalNode = command.ExecuteConfirmation(array); command.previousTerminalNode = terminalNode; return true; } Command command2 = GetCommand(array); if (command2 == null) { return false; } terminalNode = command2.Execute(array); command2.previousTerminalNode = terminalNode; return true; } public static void OnLocalDisconnect() { awaitingConfirmationCommand = null; } public static void OnTerminalQuit() { awaitingConfirmationCommand = null; } private static Command GetCommand(string[] args) { Command result = null; commands.ForEach(delegate(Command command) { if (result == null && command.IsCommand(args)) { result = command; } }); return result; } } public class LobbyCommand : Command { private const string DefaultText = "- status : prints the current lobby status\r\n\r\nSteam:\r\n- open : open the lobby\r\n- close : close the lobby\r\n- private : set lobby to Invite Only\r\n- friend : set lobby to Friends Only\r\n- public : set lobby to Public\r\n- rename [name] : change the name of the lobby\r\n\r\nSaving:\r\n- autosave : toggle autosave for the savefile\r\n- save (name) : save the lobby\r\n- load (name) : load a savefile\r\n- switch (name) : swap savefile without loading it\r\n- clear : reset the current lobby to empty\r\n\r\nExtra:\r\n- dropall : drop all items to the ground\r\n"; private const string DefaultTextLAN = "- status : prints the current lobby status\r\n\r\nLAN:\r\n- open : set the lobby to be discoverable\r\n- close : set the lobby to be non-discoverable\r\n- rename [name] : change the name of the lobby\r\n\r\nSaving:\r\n- autosave : toggle autosave for the savefile\r\n- save (name) : save the lobby\r\n- load (name) : load a savefile\r\n- switch (name) : swap savefile without loading it\r\n- clear : reset the current lobby to empty\r\n\r\nExtra:\r\n- dropall : drop all items to the ground\r\n"; public override bool IsCommand(string[] args) { if (GameNetworkManager.Instance.isHostingGame) { return args[0].Trim().ToLower() == "lobby"; } return false; } public override TerminalNode Execute(string[] args) { TerminalNode node = ScriptableObject.CreateInstance<TerminalNode>(); try { if (Utility.IsNullOrWhiteSpace(args[1])) { return HelpNode(); } switch (args[1]) { case "status": StatusCommand(ref node, args); break; case "open": { if (PerformOrbitCheck(node, out var errorText10)) { return errorText10; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { OpenCommand(ref node, args); } break; } case "close": { if (PerformOrbitCheck(node, out var errorText7)) { return errorText7; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { CloseCommand(ref node, args); } break; } case "private": { if (PerformOrbitCheck(node, out var errorText3)) { return errorText3; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { PrivateCommand(ref node, args); } break; } case "friend": { if (PerformOrbitCheck(node, out var errorText11)) { return errorText11; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { FriendCommand(ref node, args); } break; } case "public": { if (PerformOrbitCheck(node, out var errorText2)) { return errorText2; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { PublicCommand(ref node, args); } break; } case "rename": { if (PerformOrbitCheck(node, out var errorText6)) { return errorText6; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { RenameCommand(ref node, args); } break; } case "autosave": AutoSaveCommand(ref node, args); break; case "save": { if (PerformOrbitCheck(node, out var errorText8)) { return errorText8; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { SaveCommand(ref node, args); } break; } case "load": { if (PerformOrbitCheck(node, out var errorText4)) { return errorText4; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { LoadCommand(ref node, args); } break; } case "switch": { if (PerformOrbitCheck(node, out var errorText9)) { return errorText9; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { SwitchCommand(ref node, args); } break; } case "clear": { if (PerformOrbitCheck(node, out var errorText5)) { return errorText5; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { ClearCommand(ref node, args); } break; } case "dropall": { if (PerformOrbitCheck(node, out var errorText)) { return errorText; } if (!LobbyControl.CanModifyLobby) { node.displayText = "Lobby cannot be changed at the moment\n\n"; } else { DropAllCommand(ref node, args); } break; } case "help": node = HelpNode(); break; default: node = HelpNode(); node.displayText = "Invalid Command, options:\n" + node.displayText; break; } } catch (Exception ex) { LobbyControl.Log.LogError((object)("Exception:\n\n" + ex)); node.displayText = "Exception!\n\n"; } return node; } private static bool StatusCommand(ref TerminalNode node, string[] args) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) GameNetworkManager instance = GameNetworkManager.Instance; bool flag = false; string value = instance.steamLobbyName; string value2; if (instance.disableSteam) { UnityTransport component = ((Component)NetworkManager.Singleton).GetComponent<UnityTransport>(); value2 = ((component.ConnectionData.ServerListenAddress == "0.0.0.0") ? "Public" : "Private"); } else { if (!instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } Lobby value3 = instance.currentLobby.Value; flag = LobbyPatcher.IsOpen(value3); LobbyType visibility = LobbyPatcher.GetVisibility(value3); value2 = ((object)(LobbyType)(ref visibility)).ToString(); value = ((Lobby)(ref value3)).GetData("name"); } bool canSave = LobbyControl.CanSave; StringBuilder stringBuilder = new StringBuilder("Lobby Status:"); stringBuilder.Append("\n- File is '").Append(instance.currentSaveFileName).Append("'"); stringBuilder.Append("\n- Name is '").Append(value).Append("'"); if (!instance.disableSteam) { stringBuilder.Append("\n- Status is ").Append(flag ? "Open" : "Closed"); } stringBuilder.Append("\n- Visibility is ").Append(value2); stringBuilder.Append("\n- Saving is ").Append(canSave ? "Automatic" : "Manual"); stringBuilder.Append("\n\n"); node.displayText = stringBuilder.ToString(); node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool OpenCommand(ref TerminalNode node, string[] args) { LobbyControl.Log.LogDebug((object)"Reopening lobby, setting to joinable."); GameNetworkManager instance = GameNetworkManager.Instance; if (instance.disableSteam) { UnityTransport component = ((Component)NetworkManager.Singleton).GetComponent<UnityTransport>(); if (component.ConnectionData.ServerListenAddress != "0.0.0.0") { node.displayText = "Server is limited to local connections\n\n"; return false; } instance.lobbyHostSettings.isLobbyPublic = true; ES3.Save<bool>("HostSettings_Public", instance.lobbyHostSettings.isLobbyPublic, "LCGeneralSaveData"); } else if (!instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } instance.SetLobbyJoinable(true); Object.FindObjectOfType<QuickMenuManager>().inviteFriendsTextAlpha.alpha = 1f; string text = "Lobby is now Open"; LobbyControl.Log.LogInfo((object)text); node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool CloseCommand(ref TerminalNode node, string[] args) { LobbyControl.Log.LogDebug((object)"Closing lobby, setting to not joinable."); GameNetworkManager instance = GameNetworkManager.Instance; if (instance.disableSteam) { UnityTransport component = ((Component)NetworkManager.Singleton).GetComponent<UnityTransport>(); if (component.ConnectionData.ServerListenAddress != "0.0.0.0") { node.displayText = "Server is limited to local connections\n\n"; return false; } instance.lobbyHostSettings.isLobbyPublic = false; ES3.Save<bool>("HostSettings_Public", instance.lobbyHostSettings.isLobbyPublic, "LCGeneralSaveData"); } else if (!instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } instance.SetLobbyJoinable(false); Object.FindObjectOfType<QuickMenuManager>().inviteFriendsTextAlpha.alpha = 0f; string text = "Lobby is now Closed"; LobbyControl.Log.LogInfo((object)text); node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool PrivateCommand(ref TerminalNode node, string[] args) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) LobbyControl.Log.LogDebug((object)"Locking lobby, setting to Private."); GameNetworkManager instance = GameNetworkManager.Instance; if (!instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } ES3.Save<bool>("HostSettings_Public", false, "LCGeneralSaveData"); Lobby value = instance.currentLobby.Value; ((Lobby)(ref value)).SetPrivate(); string text = "Lobby is now Private"; LobbyControl.Log.LogInfo((object)text); node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool FriendCommand(ref TerminalNode node, string[] args) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) LobbyControl.Log.LogDebug((object)"Locking lobby, setting to Friends Only."); GameNetworkManager instance = GameNetworkManager.Instance; if (!instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } ES3.Save<bool>("HostSettings_Public", false, "LCGeneralSaveData"); Lobby value = instance.currentLobby.Value; ((Lobby)(ref value)).SetFriendsOnly(); string text = "Lobby is now Friends Only"; LobbyControl.Log.LogInfo((object)text); node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool PublicCommand(ref TerminalNode node, string[] args) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) LobbyControl.Log.LogDebug((object)"Unlocking lobby, setting to Public."); GameNetworkManager instance = GameNetworkManager.Instance; if (!instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } ES3.Save<bool>("HostSettings_Public", true, "LCGeneralSaveData"); Lobby value = instance.currentLobby.Value; ((Lobby)(ref value)).SetPublic(); string text = "Lobby is now Public"; LobbyControl.Log.LogInfo((object)text); node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool RenameCommand(ref TerminalNode node, string[] args) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (Utility.IsNullOrWhiteSpace(args[2])) { node.displayText = "Lobby name cannot be null\n\n"; return false; } string text = args[2]; if (text.Length > 40) { text = text.Substring(0, 40); } LobbyControl.Log.LogDebug((object)("Renaming lobby: \"" + text + "\"")); GameNetworkManager instance = GameNetworkManager.Instance; if (!instance.disableSteam && !instance.currentLobby.HasValue) { node.displayText = "Failed to fetch lobby ( was null )\n\n"; return false; } instance.lobbyHostSettings.lobbyName = text; instance.steamLobbyName = instance.lobbyHostSettings.lobbyName; if (instance.currentLobby.HasValue) { Lobby value = instance.currentLobby.Value; ((Lobby)(ref value)).SetData("name", instance.steamLobbyName); } ES3.Save<string>("HostSettings_Name", instance.steamLobbyName, "LCGeneralSaveData"); string text2 = "Lobby renamed to \"" + text + "\""; LobbyControl.Log.LogInfo((object)text2); node.displayText = text2 + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool AutoSaveCommand(ref TerminalNode node, string[] args) { LobbyControl.Log.LogDebug((object)"Toggling AutoSave"); LobbyControl.CanSave = (LobbyControl.AutoSaveEnabled = !LobbyControl.AutoSaveEnabled); string text = "AutoSaving is now " + (LobbyControl.CanSave ? "On" : "Off"); LobbyControl.Log.LogInfo((object)text); node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool SaveCommand(ref TerminalNode node, string[] args) { if (StartOfRound.Instance.isChallengeFile) { node.displayText = "Cannot Edit Challenge Save\n\n"; return false; } LobbyControl.Log.LogDebug((object)"Saving Lobby"); GameNetworkManager instance = GameNetworkManager.Instance; string currentSaveFileName = instance.currentSaveFileName; if (!Utility.IsNullOrWhiteSpace(args[2])) { string text = args[2]; if (text.Length > 20) { text = text.Substring(0, 20); } instance.currentSaveFileName = text; } if (currentSaveFileName != instance.currentSaveFileName) { ES3.CopyFile(currentSaveFileName, instance.currentSaveFileName); } LobbyControl.CanSave = true; HUDManager.Instance.saveDataIconAnimatorB.SetTrigger("save"); instance.SaveGameValues(); string text2 = "Lobby Saved to " + instance.currentSaveFileName; LobbyControl.CanSave = LobbyControl.AutoSaveEnabled; instance.currentSaveFileName = currentSaveFileName; LobbyControl.Log.LogInfo((object)text2); node.displayText = text2 + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool LoadCommand(ref TerminalNode node, string[] args) { if (StartOfRound.Instance.isChallengeFile) { node.displayText = "Cannot Edit Challenge Save\n\n"; return false; } LobbyControl.Log.LogDebug((object)"Reloading Lobby"); GameNetworkManager instance = GameNetworkManager.Instance; if (!Utility.IsNullOrWhiteSpace(args[2])) { string text = args[2]; if (text.Length > 20) { text = text.Substring(0, 20); } instance.currentSaveFileName = text; } string text2 = "Lobby '" + instance.currentSaveFileName + "' loaded"; ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(LoadLobbyCoroutine()); LobbyControl.AutoSaveEnabled = (LobbyControl.CanSave = ES3.Load<bool>("LC_SavingMethod", GameNetworkManager.Instance.currentSaveFileName, true)); LobbyControl.Log.LogInfo((object)text2); node.displayText = text2 + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool SwitchCommand(ref TerminalNode node, string[] args) { if (StartOfRound.Instance.isChallengeFile) { node.displayText = "Cannot Edit Challenge Save\n\n"; return false; } LobbyControl.Log.LogDebug((object)"Switching Lobby"); GameNetworkManager instance = GameNetworkManager.Instance; if (Utility.IsNullOrWhiteSpace(args[2])) { node.displayText = "You need to specify a destination for the swap!"; return false; } string text = args[2]; if (text.Length > 20) { text = text.Substring(0, 20); } instance.currentSaveFileName = text; string text2 = "Lobby is now saving to '" + instance.currentSaveFileName + "'"; node.displayText = text2 + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool ClearCommand(ref TerminalNode node, string[] args) { if (StartOfRound.Instance.isChallengeFile) { node.displayText = "Cannot Edit Challenge Save\n\n"; return false; } LobbyControl.Log.LogDebug((object)"Clearing Lobby"); LobbyControl.CanSave = true; GameNetworkManager.Instance.ResetSavedGameValues(); ES3.DeleteFile(GameNetworkManager.Instance.currentSaveFileName); LobbyControl.CanSave = LobbyControl.AutoSaveEnabled; bool flag = LoadCommand(ref node, new string[3]); if (flag) { node.displayText = "Lobby is now Empty!"; } return flag; } private static bool DropAllCommand(ref TerminalNode node, string[] args) { LobbyControl.Log.LogDebug((object)"Dropping all Items"); string text = "All Items Dropped"; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { val.DropAllHeldItemsAndSync(); } node.displayText = text + "\n\n"; node.maxCharactersToType = node.displayText.Length + 2; return true; } private static bool PerformOrbitCheck(TerminalNode terminalNode, out TerminalNode errorText) { if (!StartOfRound.Instance.inShipPhase) { terminalNode.displayText = "Can only be used while in Orbit\n\n"; errorText = terminalNode; return true; } errorText = null; return false; } private static TerminalNode HelpNode() { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); val.displayText = (GameNetworkManager.Instance.disableSteam ? "- status : prints the current lobby status\r\n\r\nLAN:\r\n- open : set the lobby to be discoverable\r\n- close : set the lobby to be non-discoverable\r\n- rename [name] : change the name of the lobby\r\n\r\nSaving:\r\n- autosave : toggle autosave for the savefile\r\n- save (name) : save the lobby\r\n- load (name) : load a savefile\r\n- switch (name) : swap savefile without loading it\r\n- clear : reset the current lobby to empty\r\n\r\nExtra:\r\n- dropall : drop all items to the ground\r\n" : "- status : prints the current lobby status\r\n\r\nSteam:\r\n- open : open the lobby\r\n- close : close the lobby\r\n- private : set lobby to Invite Only\r\n- friend : set lobby to Friends Only\r\n- public : set lobby to Public\r\n- rename [name] : change the name of the lobby\r\n\r\nSaving:\r\n- autosave : toggle autosave for the savefile\r\n- save (name) : save the lobby\r\n- load (name) : load a savefile\r\n- switch (name) : swap savefile without loading it\r\n- clear : reset the current lobby to empty\r\n\r\nExtra:\r\n- dropall : drop all items to the ground\r\n"); val.clearPreviousText = true; val.maxCharactersToType = val.displayText.Length + 2; return val; } private static IEnumerator LoadLobbyCoroutine() { StartOfRound startOfRound = StartOfRound.Instance; Terminal terminal = Object.FindObjectOfType<Terminal>(); startOfRound.ResetShip(); VehicleController[] array = Object.FindObjectsOfType<VehicleController>(); VehicleController[] array2 = array; foreach (VehicleController val in array2) { if ((Object)(object)((NetworkBehaviour)val).NetworkObject != (Object)null) { ((NetworkBehaviour)val).NetworkObject.Despawn(false); } } bool mem = GameNetworkManager.Instance.gameHasStarted; GameNetworkManager.Instance.gameHasStarted = false; foreach (KeyValuePair<int, GameObject> item in StartOfRound.Instance.SpawnedShipUnlockables.ToList()) { UnlockableItem val2 = startOfRound.unlockablesList.unlockables[item.Key]; if (val2.alreadyUnlocked && val2.spawnPrefab && !((Object)(object)item.Value == (Object)null)) { NetworkObject component = item.Value.GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { component.Despawn(true); } } } startOfRound.SpawnedShipUnlockables.Clear(); startOfRound.suitsPlaced = 0; GameNetworkManager.Instance.ResetUnlockablesListValues(false); yield return (object)new WaitForSeconds(0.2f); startOfRound.SetTimeAndPlanetToSavedSettings(); startOfRound.SetMapScreenInfoToCurrentLevel(); terminal.Start(); if (startOfRound.connectedPlayersAmount >= 1) { RefreshLobby(); } ReloadUnlockables(); yield return (object)new WaitForSeconds(0.2f); startOfRound.LoadAttachedVehicle(); yield return (object)new WaitForSeconds(0.1f); startOfRound.LoadShipGrabbableItems(); yield return (object)new WaitForSeconds(0.1f); if (startOfRound.connectedPlayersAmount >= 1) { startOfRound.SyncShipUnlockablesServerRpc(); } GameNetworkManager.Instance.gameHasStarted = mem; } private static void ReloadUnlockables() { //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; instance.LoadUnlockables(); try { for (int i = 0; i < instance.unlockablesList.unlockables.Count; i++) { UnlockableItem val = instance.unlockablesList.unlockables[i]; if (!val.alreadyUnlocked) { continue; } LobbyControl.Log.LogWarning((object)(val.unlockableName + " starting")); if (!instance.SpawnedShipUnlockables.ContainsKey(i)) { instance.SpawnUnlockable(i); } PlaceableShipObject val2 = instance.SpawnedShipUnlockables[i].GetComponent<PlaceableShipObject>(); if (val2 == null) { val2 = instance.SpawnedShipUnlockables[i].GetComponentInChildren<PlaceableShipObject>(); } if (val2 == null) { continue; } LobbyControl.Log.LogWarning((object)(val.unlockableName + " continuing")); AutoParentToShip parentObject = val2.parentObject; if ((Object)(object)parentObject != (Object)null) { LobbyControl.Log.LogWarning((object)(val.unlockableName + " parentObject")); if (val.inStorage) { val2.parentObject.disableObject = true; } Vector3 positionOffset = parentObject.positionOffset; Vector3 val3 = instance.elevatorTransform.TransformPoint(positionOffset); Vector3 position = ((Component)val2.mainMesh).transform.position; Vector3 placedPosition = val3 - (((Component)val2.parentObject).transform.position - position) - (position - ((Component)val2.placeObjectCollider).transform.position); val.placedPosition = placedPosition; Quaternion val4 = Quaternion.Euler(parentObject.rotationOffset); Quaternion val5 = val4 * Quaternion.Inverse(((Component)parentObject).transform.rotation); Quaternion val6 = val5 * ((Component)val2.mainMesh).transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref val6)).eulerAngles; val.placedRotation = eulerAngles; } else { LobbyControl.Log.LogWarning((object)(val.unlockableName + " parentObjectSecondary")); Transform parentObjectSecondary = val2.parentObjectSecondary; Vector3 position2 = parentObjectSecondary.position; Transform transform = ((Component)val2.mainMesh).transform; Vector3 position3 = transform.position; Vector3 placedPosition2 = position2 - (((Component)parentObjectSecondary).transform.position - position3 + (position3 - ((Component)val2.placeObjectCollider).transform.position)); val.placedPosition = placedPosition2; Quaternion rotation = parentObjectSecondary.rotation; Quaternion val7 = rotation * Quaternion.Inverse(transform.rotation); Vector3 eulerAngles2 = ((Quaternion)(ref val7)).eulerAngles; val.placedRotation = eulerAngles2; } } if (instance.connectedPlayersAmount < 1) { return; } List<ulong> targetClientIds = instance.ClientPlayerList.Keys.ToList(); ClientRpcParams val8 = default(ClientRpcParams); val8.Send = new ClientRpcSendParams { TargetClientIds = targetClientIds }; ClientRpcParams val9 = val8; for (int j = 0; j < instance.unlockablesList.unlockables.Count; j++) { UnlockableItem val10 = instance.unlockablesList.unlockables[j]; if (val10.alreadyUnlocked && !val10.inStorage) { FastBufferWriter val11 = ((NetworkBehaviour)instance).__beginSendClientRpc(1076853239u, val9, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val11, j); ((NetworkBehaviour)instance).__endSendClientRpc(ref val11, 1076853239u, val9, (RpcDelivery)0); } } instance.SyncShipUnlockablesServerRpc(); } catch (Exception ex) { LobbyControl.Log.LogError((object)ex); } } private static void RefreshLobby() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; List<ulong> list = new List<ulong>(); List<ulong> list2 = new List<ulong>(); for (int i = 0; i < instance.allPlayerObjects.Length; i++) { NetworkObject component = instance.allPlayerObjects[i].GetComponent<NetworkObject>(); if (!component.IsOwnedByServer) { list.Add(component.OwnerClientId); list2.Add(component.OwnerClientId); } else if (i == 0) { list.Add(NetworkManager.Singleton.LocalClientId); } else { list.Add(999uL); } } ClientRpcParams val = default(ClientRpcParams); val.Send = new ClientRpcSendParams { TargetClientIds = list2 }; ClientRpcParams val2 = val; int groupCredits = Object.FindObjectOfType<Terminal>().groupCredits; int profitQuota = TimeOfDay.Instance.profitQuota; int quotaFulfilled = TimeOfDay.Instance.quotaFulfilled; int num = (int)TimeOfDay.Instance.timeUntilDeadline; PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; FastBufferWriter val3 = ((NetworkBehaviour)instance).__beginSendClientRpc(886676601u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val3, localPlayerController.actualClientId); BytePacker.WriteValueBitPacked(val3, instance.connectedPlayersAmount - 1); bool flag = true; ((FastBufferWriter)(ref val3)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); ((FastBufferWriter)(ref val3)).WriteValueSafe<ulong>(list.ToArray(), default(ForPrimitives)); BytePacker.WriteValueBitPacked(val3, instance.ClientPlayerList[localPlayerController.actualClientId]); BytePacker.WriteValueBitPacked(val3, groupCredits); BytePacker.WriteValueBitPacked(val3, instance.currentLevelID); BytePacker.WriteValueBitPacked(val3, profitQuota); BytePacker.WriteValueBitPacked(val3, num); BytePacker.WriteValueBitPacked(val3, quotaFulfilled); BytePacker.WriteValueBitPacked(val3, instance.randomMapSeed); ((FastBufferWriter)(ref val3)).WriteValueSafe<bool>(ref instance.isChallengeFile, default(ForPrimitives)); ((NetworkBehaviour)instance).__endSendClientRpc(ref val3, 886676601u, val2, (RpcDelivery)0); } } } namespace LobbyControl.PopUp { [HarmonyPatch] public class PopUpPatch { public static readonly List<Tuple<string, string>> PopUps = new List<Tuple<string, string>>(); [HarmonyPrefix] [HarmonyPatch(typeof(MenuManager), "Awake")] private static void AddPopups(MenuManager __instance) { foreach (Tuple<string, string> popUp in PopUps) { AppendPopup(popUp.Item1, popUp.Item2); } } private static void AppendPopup(string name, string text) { GameObject val = GameObject.Find("/Canvas/MenuContainer/"); GameObject val2 = GameObject.Find("Canvas/MenuContainer/LANWarning/"); if (!((Object)(object)val2 == (Object)null)) { GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform); ((Object)val3).name = name; val3.SetActive(true); GameObject val4 = GameObject.Find("Canvas/MenuContainer/" + name + "/Panel/NotificationText"); TextMeshProUGUI component = val4.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = text; } } } } namespace LobbyControl.Patches { [HarmonyPatch] internal class DebugPatches { private static void test() { } } [HarmonyPatch] public class ItemSyncPatches { [HarmonyPatch] internal class GhostItemPatches { [HarmonyFinalizer] [HarmonyPatch(typeof(PlayerControllerB), "GrabObjectServerRpc")] private static Exception CheckOverflow(PlayerControllerB __instance, Exception __exception, NetworkObjectReference grabbedObject) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (__exception != null) { __instance.GrabObjectClientRpc(false, grabbedObject); } return __exception; } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "GrabObjectServerRpc")] private static IEnumerable<CodeInstruction> CheckOverflow(IEnumerable<CodeInstruction> instructions) { //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); FieldInfo field = typeof(GrabbableObject).GetField("heldByPlayerOnServer"); MethodInfo method = typeof(GhostItemPatches).GetMethod("CheckGrab", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo method2 = typeof(GhostItemPatches).GetMethod("CheckOwnership", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.IsLdarga(list[i], (int?)null)) { if (!CodeInstructionExtensions.IsStloc(list[i - 1], (LocalBuilder)null)) { continue; } list[i - 3] = new CodeInstruction(OpCodes.Ldarg_0, (object)null) { labels = list[i - 3].labels, blocks = list[i - 3].blocks }; list[i - 2] = new CodeInstruction(OpCodes.Call, (object)method) { labels = list[i - 2].labels, blocks = list[i - 2].blocks }; list.Insert(i - 2, new CodeInstruction(OpCodes.Ldarg_1, (object)null) { blocks = list[i - 2].blocks }); i++; LobbyControl.Log.LogDebug((object)"Patched GrabObjectServerRpc 1!!"); } if (CodeInstructionExtensions.LoadsField(list[i], field, false)) { list[i - 1] = new CodeInstruction(OpCodes.Ldarg_0, (object)null) { labels = list[i - 1].labels, blocks = list[i - 1].blocks }; list[i] = new CodeInstruction(OpCodes.Call, (object)method2) { labels = list[i].labels, blocks = list[i].blocks }; LobbyControl.Log.LogDebug((object)"Patched GrabObjectServerRpc 2!!"); } } return list; } private static bool CheckOwnership(NetworkObject gNetworkObject, PlayerControllerB instance) { bool value = LobbyControl.PluginConfig.ItemSync.GhostItems.Value; GrabbableObject componentInChildren = ((Component)gNetworkObject).GetComponentInChildren<GrabbableObject>(); if (componentInChildren.heldByPlayerOnServer) { if (value) { return (Object)(object)componentInChildren.playerHeldBy != (Object)(object)instance; } return true; } return false; } private static bool CheckGrab(PlayerControllerB controllerB, NetworkObjectReference currentlyGrabbing) { if (!LobbyControl.PluginConfig.ItemSync.GhostItems.Value) { return true; } NetworkObject val = default(NetworkObject); if (ReservedItemSlotChecker.Enabled && ((NetworkObjectReference)(ref currentlyGrabbing)).TryGet(ref val, (NetworkManager)null)) { GrabbableObject componentInChildren = ((Component)val).GetComponentInChildren<GrabbableObject>(); if ((Object)(object)componentInChildren != (Object)null && ReservedItemSlotChecker.HasEmptySlotForReservedItem(controllerB, componentInChildren)) { LobbyControl.Log.LogDebug((object)("Attempted Grab for " + controllerB.playerUsername + ", was Reserved slot")); return true; } } int num = controllerB.FirstEmptyItemSlot(); bool flag = num < controllerB.ItemSlots.Length && num >= 0; LobbyControl.Log.LogDebug((object)$"Attempted Grab for {controllerB.playerUsername}, slot {num}, max {controllerB.ItemSlots.Length}"); if (!flag) { LobbyControl.Log.LogError((object)("Grab invalidated for " + controllerB.playerUsername + " out of inventory space!" + (LobbyControl.PluginConfig.ItemSync.ForceDrop.Value ? "" : " ( use lobby dropall to fix )"))); HUDManager.Instance.AddTextToChatOnServer(controllerB.playerUsername + " is out of inventory space!", -1); if (LobbyControl.PluginConfig.ItemSync.ForceDrop.Value) { controllerB.DropAllHeldItemsServerRpc(); } } else { LobbyControl.Log.LogInfo((object)("Grab validated for " + controllerB.playerUsername + "!")); } return flag; } } [HarmonyPatch] internal class ShotgunPatch { [HarmonyPrefix] [HarmonyPatch(typeof(PlayerControllerB), "DestroyItemInSlotServerRpc")] private static bool CheckDestroy(PlayerControllerB __instance, int itemSlot) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return true; } if ((int)((NetworkBehaviour)__instance).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return true; } if (!LobbyControl.PluginConfig.ItemSync.ShotGunReload.Value) { return true; } int num = -1; int num2 = -1; GrabbableObject[] itemSlots = __instance.ItemSlots; foreach (GrabbableObject val in itemSlots) { num2++; ShotgunItem val2 = (ShotgunItem)(object)((val is ShotgunItem) ? val : null); if ((Object)(object)val2 != (Object)null && val2.isReloading) { num = val2.FindAmmoInInventory(); break; } } if (num == -1 || num == itemSlot) { return true; } LobbyControl.Log.LogWarning((object)(__instance.playerUsername + " was found de-synced while reloading shotgun! attempting sync.")); if (!ReservedItemSlotChecker.Enabled || !ReservedItemSlotChecker.CheckIfReservedItemSlot(__instance, num2)) { __instance.SwitchToItemSlot(num2, (GrabbableObject)null); } ClientRpcParams val3 = default(ClientRpcParams); val3.Send = new ClientRpcSendParams { TargetClientIds = new ulong[1] { __instance.actualClientId } }; ClientRpcParams val4 = val3; FastBufferWriter val5 = ((NetworkBehaviour)__instance).__beginSendClientRpc(899109231u, val4, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val5, itemSlot); ((NetworkBehaviour)__instance).__endSendClientRpc(ref val5, 899109231u, val4, (RpcDelivery)0); val3 = default(ClientRpcParams); val3.Send = new ClientRpcSendParams { TargetClientIds = new ulong[1] { NetworkManager.Singleton.LocalClientId } }; ClientRpcParams val6 = val3; FastBufferWriter val7 = ((NetworkBehaviour)__instance).__beginSendClientRpc(899109231u, val6, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val7, num); ((NetworkBehaviour)__instance).__endSendClientRpc(ref val7, 899109231u, val6, (RpcDelivery)0); return false; } } [HarmonyPatch] internal class GenericUsablePatch { [HarmonyPrefix] [HarmonyPatch(typeof(GrabbableObject), "ActivateItemClientRpc")] private static void CheckUse(GrabbableObject __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening || (int)((NetworkBehaviour)__instance).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || ((NetworkBehaviour)__instance).IsOwner || !LobbyControl.PluginConfig.ItemSync.SyncOnUse.Value || LobbyControl.PluginConfig.ItemSync.SyncIgnoreName.Value.Split(',').Contains(__instance.itemProperties.itemName) || (Object)(object)__instance == (Object)(object)__instance.playerHeldBy.currentlyHeldObjectServer) { return; } int num = -1; for (int i = 0; i < __instance.playerHeldBy.ItemSlots.Length; i++) { GrabbableObject val = __instance.playerHeldBy.ItemSlots[i]; if ((Object)(object)val == (Object)(object)__instance) { num = i; break; } } if (num != -1 && (!ReservedItemSlotChecker.Enabled || !ReservedItemSlotChecker.CheckIfReservedItemSlot(__instance.playerHeldBy, num))) { LobbyControl.Log.LogWarning((object)(__instance.playerHeldBy.playerUsername + " was found de-synced while using an item! attempting sync.")); __instance.playerHeldBy.SwitchToItemSlot(num, (GrabbableObject)null); } } [HarmonyPrefix] [HarmonyPatch(typeof(GrabbableObject), "InteractLeftRightClientRpc")] private static void CheckInteract(GrabbableObject __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening || (int)((NetworkBehaviour)__instance).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || ((NetworkBehaviour)__instance).IsOwner || !LobbyControl.PluginConfig.ItemSync.SyncOnInteract.Value || LobbyControl.PluginConfig.ItemSync.SyncIgnoreName.Value.Split(',').Contains(__instance.itemProperties.itemName) || (Object)(object)__instance == (Object)(object)__instance.playerHeldBy.currentlyHeldObject) { return; } int num = -1; for (int i = 0; i < __instance.playerHeldBy.ItemSlots.Length; i++) { GrabbableObject val = __instance.playerHeldBy.ItemSlots[i]; if ((Object)(object)val == (Object)(object)__instance) { num = i; break; } } if (num != -1 && (!ReservedItemSlotChecker.Enabled || !ReservedItemSlotChecker.CheckIfReservedItemSlot(__instance.playerHeldBy, num))) { LobbyControl.Log.LogWarning((object)(__instance.playerHeldBy.playerUsername + " was found de-synced while interacting with an item! attempting sync.")); __instance.playerHeldBy.SwitchToItemSlot(num, (GrabbableObject)null); } } } } [HarmonyPatch] internal class JoinPatches { internal static bool isLanding = false; private static readonly ConcurrentQueue<ConnectionApprovalResponse> ConnectionQueue = new ConcurrentQueue<ConnectionApprovalResponse>(); private static readonly object Lock = new object(); private static ulong? _currentConnectingPlayer; private static ulong _currentConnectingExpiration; private static readonly bool[] CurrentConnectingPlayerConfirmations = new bool[2]; [HarmonyTranspiler] [HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")] private static IEnumerable<CodeInstruction> FixConnectionApprovalPrefix(IEnumerable<CodeInstruction> instructions) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown FieldInfo fieldInfo = AccessTools.Field(typeof(GameNetworkManager), "gameHasStarted"); List<CodeInstruction> list = instructions.ToList(); Label? label = default(Label?); for (int i = 0; i < list.Count; i++) { CodeInstruction val = list[i]; if (CodeInstructionExtensions.LoadsField(val, fieldInfo, false)) { CodeInstruction val2 = list[i + 1]; CodeInstruction val3 = list[i - 1]; if (CodeInstructionExtensions.Branches(val2, ref label)) { list[i - 1] = new CodeInstruction(OpCodes.Nop, (object)null) { labels = val3.labels, blocks = val3.blocks }; list[i] = new CodeInstruction(OpCodes.Nop, (object)null) { labels = val.labels, blocks = val.blocks }; list[i + 1] = new CodeInstruction(OpCodes.Br, (object)label) { labels = val2.labels, blocks = val2.blocks }; LobbyControl.Log.LogDebug((object)"Patched ConnectionApproval!!"); break; } } } return list; } [HarmonyFinalizer] [HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")] [HarmonyPriority(10)] private static Exception ThrottleApprovals(GameNetworkManager __instance, ConnectionApprovalRequest request, ConnectionApprovalResponse response, Exception __exception) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (__exception != null) { return __exception; } if (!response.Approved) { return null; } if (isLanding) { LobbyControl.Log.LogDebug((object)"connection refused ( ship was landed )."); response.Reason = "Ship has already landed!"; response.Approved = false; return null; } if (!__instance.disableSteam && (!__instance.currentLobby.HasValue || !LobbyPatcher.IsOpen(__instance.currentLobby.Value))) { LobbyControl.Log.LogDebug((object)"connection refused ( lobby was closed )."); response.Reason = "Lobby has been closed!"; response.Approved = false; return null; } if (__instance.gameHasStarted) { LobbyControl.Log.LogDebug((object)"Incoming late connection."); } if (!LobbyControl.PluginConfig.JoinQueue.Enabled.Value) { return null; } response.Pending = true; ConnectionQueue.Enqueue(response); LobbyControl.Log.LogWarning((object)$"Connection request Enqueued! count:{ConnectionQueue.Count}"); return null; } [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] private static void OnClientConnect(StartOfRound __instance, ulong clientId) { lock (Lock) { if (((NetworkBehaviour)__instance).IsServer && LobbyControl.PluginConfig.JoinQueue.Enabled.Value) { CurrentConnectingPlayerConfirmations[0] = false; CurrentConnectingPlayerConfirmations[1] = false; _currentConnectingPlayer = clientId; _currentConnectingExpiration = (ulong)(Environment.TickCount + LobbyControl.PluginConfig.JoinQueue.ConnectionTimeout.Value); } } } [HarmonyFinalizer] [HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")] private static void ResetForDc(StartOfRound __instance, int playerObjectNumber) { GameObject val = __instance.allPlayerObjects[playerObjectNumber]; PlayerControllerB val2 = __instance.allPlayerScripts[playerObjectNumber]; val.transform.parent = __instance.playersContainer; val2.justConnected = true; val2.isCameraDisabled = true; } [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientDisconnectCallback")] private static void OnClientDisconnect(GameNetworkManager __instance, ulong clientId) { if (!__instance.isHostingGame) { return; } LobbyControl.Log.LogInfo((object)$"{clientId} disconnected"); lock (Lock) { if (_currentConnectingPlayer == clientId) { _currentConnectingPlayer = null; _currentConnectingExpiration = 0uL; } } } internal static void Init() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(StartOfRound), "SyncAlreadyHeldObjectsServerRpc", (Type[])null, (Type[])null); if (Utils.TryGetRpcID(methodInfo, out var rpcID)) { MethodInfo methodInfo2 = AccessTools.Method(typeof(StartOfRound), $"__rpc_handler_{rpcID}", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(JoinPatches), "ClientConnectionCompleted1", (Type[])null, (Type[])null); LobbyControl._harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null); } methodInfo = AccessTools.Method(typeof(PlayerControllerB), "SendNewPlayerValuesServerRpc", (Type[])null, (Type[])null); if (Utils.TryGetRpcID(methodInfo, out rpcID)) { MethodInfo methodInfo4 = AccessTools.Method(typeof(PlayerControllerB), $"__rpc_handler_{rpcID}", (Type[])null, (Type[])null); MethodInfo methodInfo5 = AccessTools.Method(typeof(JoinPatches), "ClientConnectionCompleted2", (Type[])null, (Type[])null); LobbyControl._harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo5), (HarmonyMethod)null); } MethodInfo methodInfo6 = AccessTools.Method(typeof(StartOfRound), "StartGame", (Type[])null, (Type[])null); if (methodInfo6 != null) { LobbyControl.Hooks.Add(new Hook((MethodBase)methodInfo6, (Delegate)new Action<Action<StartOfRound>, StartOfRound>(CheckValidStart), new HookConfig { Priority = 999 })); } else { LobbyControl.Log.LogFatal((object)"Cannot apply patch to StartGame"); } } private static void ClientConnectionCompleted1(NetworkBehaviour target, __RpcParams rpcParams) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) StartOfRound val = (StartOfRound)target; if (!((NetworkBehaviour)val).IsServer) { return; } ulong senderClientId = rpcParams.Server.Receive.SenderClientId; lock (Lock) { if (_currentConnectingPlayer == senderClientId) { CurrentConnectingPlayerConfirmations[0] = true; if (CurrentConnectingPlayerConfirmations[1] || GameNetworkManager.Instance.disableSteam) { LobbyControl.Log.LogWarning((object)$"{senderClientId} completed the connection"); _currentConnectingPlayer = null; _currentConnectingExpiration = (ulong)(Environment.TickCount + LobbyControl.PluginConfig.JoinQueue.ConnectionDelay.Value); } else { LobbyControl.Log.LogWarning((object)$"{senderClientId} is waiting to synchronize the name"); } } } } private static void ClientConnectionCompleted2(NetworkBehaviour target, __RpcParams rpcParams) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = (PlayerControllerB)target; if (!((NetworkBehaviour)val).IsServer) { return; } ulong senderClientId = rpcParams.Server.Receive.SenderClientId; lock (Lock) { if (_currentConnectingPlayer == senderClientId) { CurrentConnectingPlayerConfirmations[1] = true; if (CurrentConnectingPlayerConfirmations[0]) { LobbyControl.Log.LogWarning((object)$"{senderClientId} completed the connection"); _currentConnectingPlayer = null; _currentConnectingExpiration = (ulong)(Environment.TickCount + LobbyControl.PluginConfig.JoinQueue.ConnectionDelay.Value); } else { LobbyControl.Log.LogWarning((object)$"{senderClientId} is waiting to synchronize the held items"); } } } } [HarmonyFinalizer] [HarmonyPatch(typeof(StartOfRound), "LateUpdate")] private static void ProcessConnectionQueue(StartOfRound __instance) { if (!((NetworkBehaviour)__instance).IsServer || !Monitor.TryEnter(Lock)) { return; } try { if (_currentConnectingPlayer.HasValue) { if ((ulong)Environment.TickCount < _currentConnectingExpiration) { return; } if (_currentConnectingPlayer.Value != 0L) { LobbyControl.Log.LogWarning((object)$"Connection to {_currentConnectingPlayer.Value} expired, Disconnecting!"); try { NetworkManager.Singleton.DisconnectClient(_currentConnectingPlayer.Value); } catch (Exception ex) { LobbyControl.Log.LogError((object)ex); } } _currentConnectingPlayer = null; _currentConnectingExpiration = 0uL; } else if (__instance.inShipPhase) { if ((ulong)Environment.TickCount >= _currentConnectingExpiration && ConnectionQueue.TryDequeue(out var result)) { LobbyControl.Log.LogWarning((object)$"Connection request Resumed! remaining: {ConnectionQueue.Count}"); result.Pending = false; if (result.Approved) { CurrentConnectingPlayerConfirmations[0] = false; CurrentConnectingPlayerConfirmations[1] = false; _currentConnectingPlayer = 0uL; _currentConnectingExpiration = (ulong)Environment.TickCount + 1000uL; } } } else { if (ConnectionQueue.IsEmpty) { return; } foreach (ConnectionApprovalResponse item in ConnectionQueue) { item.Approved = false; item.Reason = "ship has landed!"; item.Pending = false; } ConnectionQueue.Clear(); } } catch (Exception ex2) { LobbyControl.Log.LogError((object)ex2); } finally { Monitor.Exit(Lock); } } [HarmonyFinalizer] [HarmonyPatch(typeof(StartOfRound), "OnLocalDisconnect")] private static void FlushConnectionQueue() { lock (Lock) { CurrentConnectingPlayerConfirmations[0] = false; CurrentConnectingPlayerConfirmations[1] = false; _currentConnectingPlayer = null; _currentConnectingExpiration = 0uL; if (ConnectionQueue.Count > 0) { LobbyControl.Log.LogWarning((object)$"Disconnecting with {ConnectionQueue.Count} pending connection, Flushing!"); } ConnectionApprovalResponse result; while (ConnectionQueue.TryDequeue(out result)) { result.Reason = "Host has disconnected!"; result.Approved = false; result.Pending = false; } } } private static bool CanStartGame() { if (!_currentConnectingPlayer.HasValue) { return ConnectionQueue.IsEmpty; } return false; } private static void CheckValidStart(Action<StartOfRound> orig, StartOfRound @this) { if (!((NetworkBehaviour)@this).IsServer || !@this.inShipPhase) { orig(@this); } else if (!CanStartGame()) { int num = ConnectionQueue.Count + (_currentConnectingPlayer.HasValue ? 1 : 0); StartMatchLever val = Object.FindAnyObjectByType<StartMatchLever>(); val.CancelStartGame(); val.CancelStartGameClientRpc(); HUDManager.Instance.DisplayTip("GAME START CANCELLED", $"{num} Players Connecting!!", true, false, "LC_Tip1"); HUDManager.Instance.AddTextMessageServerRpc($"there are still {num} Players connecting!!\n"); } else { isLanding = true; orig(@this); } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")] [HarmonyPatch(typeof(StartOfRound), "Start")] private static void OnReadyToLand() { isLanding = false; } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "SendNewPlayerValuesClientRpc")] private static IEnumerable<CodeInstruction> FixRadarNames(IEnumerable<CodeInstruction> instructions) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown if (!LobbyControl.PluginConfig.SteamLobby.RadarFix.Value) { return instructions; } List<CodeInstruction> list = instructions.ToList(); FieldInfo field = typeof(TransformAndName).GetField("name"); MethodInfo method = typeof(JoinPatches).GetMethod("SetNewName", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); for (int i = 0; i < list.Count; i++) { CodeInstruction val = list[i]; if (!CodeInstructionExtensions.StoresField(val, field)) { continue; } for (int j = i - 6; j < i; j++) { CodeInstruction val2 = list[j]; if (!CodeInstructionExtensions.IsLdloc(val2, (LocalBuilder)null)) { list[j] = new CodeInstruction(OpCodes.Nop, (object)null) { blocks = val2.blocks, labels = val2.labels }; } } list[i] = new CodeInstruction(OpCodes.Call, (object)method) { blocks = val.blocks, labels = val.labels }; LobbyControl.Log.LogDebug((object)"SendNewPlayerValuesClientRpc patched!"); } return list; } private static void SetNewName(int index, string name) { StartOfRound instance = StartOfRound.Instance; GameObject val = instance.allPlayerObjects[index]; instance.mapScreen.ChangeNameOfTargetTransform(val.transform, name); } } [HarmonyPatch] internal class LimitPatcher { [HarmonyTranspiler] [HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesClientRpc")] private static IEnumerable<CodeInstruction> PacketSizePatch(IEnumerable<CodeInstruction> instructions) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown if (!LobbyControl.PluginConfig.SaveLimit.Enabled.Value) { return instructions; } MethodInfo method = typeof(NetworkBehaviour).GetMethod("__beginSendClientRpc", BindingFlags.Instance | BindingFlags.NonPublic); ConstructorInfo constructor = typeof(FastBufferWriter).GetConstructor(new Type[3] { typeof(int), typeof(Allocator), typeof(int) }); List<CodeInstruction> list = instructions.ToList(); CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)method, (string)null) }); if (val.IsInvalid) { LobbyControl.Log.LogWarning((object)"PacketSize patch failed 1!!"); LobbyControl.Log.LogDebug((object)string.Join("\n", val.Instructions())); return list; } val.Advance(1); val.Insert((CodeInstruction[])(object)new CodeInstruction[5] { new CodeInstruction(OpCodes.Pop, (object)null), new CodeInstruction(OpCodes.Ldc_I4, (object)1024), new CodeInstruction(OpCodes.Ldc_I4_2, (object)null), new CodeInstruction(OpCodes.Ldc_I4, (object)int.MaxValue), new CodeInstruction(OpCodes.Newobj, (object)constructor) }); LobbyControl.Log.LogDebug((object)"Patched PacketSize!"); return val.Instructions(); } [HarmonyTranspiler] [HarmonyPriority(800)] [HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesServerRpc")] private static IEnumerable<CodeInstruction> SyncUnlockablesPatch(IEnumerable<CodeInstruction> instructions) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown if (!LobbyControl.PluginConfig.SaveLimit.Enabled.Value) { return instructions; } MethodInfo method = typeof(GrabbableObject).GetMethod("GetItemDataToSave"); List<CodeInstruction> list = instructions.ToList(); CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null); val.End(); val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)method, (string)null) }); if (val.IsInvalid) { LobbyControl.Log.LogWarning((object)"SyncShipUnlockablesServerRpc patch failed 1!!"); LobbyControl.Log.LogDebug((object)string.Join("\n", val.Instructions())); return list; } val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ble, (object)null, (string)null) }); if (val.IsInvalid) { LobbyControl.Log.LogWarning((object)"SyncShipUnlockablesServerRpc patch failed 2!!"); LobbyControl.Log.LogDebug((object)string.Join("\n", val.Instructions())); return list; } List<Label> labels = val.Labels; val.RemoveInstructions(6); val.AddLabels((IEnumerable<Label>)labels); LobbyControl.Log.LogDebug((object)"Patched SyncShipUnlockablesServerRpc!!"); return val.Instructions(); } [HarmonyTranspiler] [HarmonyPriority(800)] [HarmonyPatch(typeof(GameNetworkManager), "SaveItemsInShip")] private static IEnumerable<CodeInstruction> SaveItemsInShipPatch(IEnumerable<CodeInstruction> instructions) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown if (!LobbyControl.PluginConfig.SaveLimit.Enabled.Value) { return instructions; } FieldInfo field = typeof(StartOfRound).GetField("maxShipItemCapacity"); MethodInfo getMethod = typeof(StartOfRound).GetProperty("Instance").GetMethod; List<CodeInstruction> list = instructions.ToList(); CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4] { new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)getMethod, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)field, (string)null), new CodeMatch((OpCode?)OpCodes.Bgt, (object)null, (string)null) }); if (val.IsInvalid) { LobbyControl.Log.LogWarning((object)"SaveItemsInShip patch failed 1!!"); LobbyControl.Log.LogDebug((object)string.Join("\n", val.Instructions())); return list; } List<Label> labels = val.Labels; val.RemoveInstructions(4); val.AddLabels((IEnumerable<Label>)labels); LobbyControl.Log.LogDebug((object)"Patched SaveItemsInShip!!"); return val.Instructions(); } } [HarmonyPatch] internal class LobbyPatcher { private static readonly Dictionary<Lobby, LobbyType> Visibility = new Dictionary<Lobby, LobbyType>(); private static readonly Dictionary<Lobby, bool> Open = new Dictionary<Lobby, bool>(); [HarmonyPostfix] [HarmonyPatch(typeof(Lobby), "SetJoinable")] private static void TrackOpenStatus(Lobby __instance, object[] __args, bool __runOriginal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (__runOriginal) { Open[__instance] = (bool)__args[0]; } } [HarmonyPostfix] [HarmonyPatch(typeof(Lobby), "SetPublic")] private static void TrackPublicStatus(Lobby __instance, bool __runOriginal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (__runOriginal) { Visibility[__instance] = (LobbyType)2; } } [HarmonyPostfix] [HarmonyPatch(typeof(Lobby), "SetPrivate")] private static void TrackPrivateStatus(Lobby __instance, bool __runOriginal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (__runOriginal) { Visibility[__instance] = (LobbyType)0; } } [HarmonyPostfix] [HarmonyPatch(typeof(Lobby), "SetFriendsOnly")] private static void trackFriendsOnly(Lobby __instance, bool __runOriginal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (__runOriginal) { Visibility[__instance] = (LobbyType)1; } } [HarmonyPostfix] [HarmonyPatch(typeof(Lobby), "SetData")] private static void trackData(Lobby __instance, bool __runOriginal, string key, string value) { } public static LobbyType GetVisibility(Lobby lobby) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!Visibility.ContainsKey(lobby)) { return (LobbyType)0; } return Visibility[lobby]; } public static bool IsOpen(Lobby lobby) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Open.ContainsKey(lobby)) { return GeneralExtensions.GetValueSafe<Lobby, bool>(Open, lobby); } return true; } } [HarmonyPatch] internal class LogSpamFix { [HarmonyPatch(typeof(EnemyAI))] internal class EnemyAIPatch { [HarmonyPrefix] [HarmonyPatch("SetDestinationToPosition")] private static bool StopIfDead1(EnemyAI __instance) { if (!LobbyControl.PluginConfig.LogSpam.Enabled.Value || !LobbyControl.PluginConfig.LogSpam.CalculatePolygonPath.Value) { return true; } return !__instance.isEnemyDead; } [HarmonyPrefix] [HarmonyPatch("DoAIInterval")] private static void StopIfDead2(EnemyAI __instance) { if (LobbyControl.PluginConfig.LogSpam.Enabled.Value && LobbyControl.PluginConfig.LogSpam.CalculatePolygonPath.Value && __instance.isEnemyDead) { __instance.moveTowardsDestination = false; } } [HarmonyPrefix] [HarmonyPatch("PathIsIntersectedByLineOfSight")] private static bool StopIfDead3(EnemyAI __instance) { if (!LobbyControl.PluginConfig.LogSpam.Enabled.Value || !LobbyControl.PluginConfig.LogSpam.CalculatePolygonPath.Value) { return true; } return !__instance.isEnemyDead; } } [HarmonyPatch] internal class AudioSpatializerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(NetworkSceneManager), "OnSceneLoaded")] private static void DisableSpatializers() { if (!LobbyControl.PluginConfig.LogSpam.AudioSpatializer.Value || !Utility.IsNullOrWhiteSpace(AudioSettings.GetSpatializerPluginName())) { return; } try { AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>(); AudioSource[] array2 = array; foreach (AudioSource val in array2) { if (val.spatialize) { val.spatialize = false; } } } catch (Exception arg) { LobbyControl.Log.LogError((object)$"Exception disabling spatializers: {arg}"); } } } } [HarmonyPatch] internal class NetworkPatcher { [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "InviteFriendsButton")] private static void FixFriendInviteButton(bool __runOriginal) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (__runOriginal) { GameNetworkManager instance = GameNetworkManager.Instance; if (GameNetworkManager.Instance.gameHasStarted && instance.currentLobby.HasValue && LobbyPatcher.IsOpen(instance.currentLobby.Value)) { GameNetworkManager.Instance.InviteFriendsUI(); } } } [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")] private static bool PreventSteamLobbyLeaving(GameNetworkManager __instance) { LobbyControl.Log.LogDebug((object)"Preventing the closing of Steam lobby."); return false; } [HarmonyPrefix] [HarmonyPriority(0)] [HarmonyPatch(typeof(StartOfRound), "StartGame")] private static void CloseSteamLobby(StartOfRound __instance, bool __runOriginal) { if (__runOriginal && ((NetworkBehaviour)__instance).IsServer && __instance.inShipPhase) { LobbyControl.Log.LogDebug((object)"Setting lobby to not joinable."); LobbyControl.CanModifyLobby = false; GameNetworkManager.Instance.SetLobbyJoinable(false); Object.FindObjectOfType<QuickMenuManager>().inviteFriendsTextAlpha.alpha = 0f; } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Start")] private static void ResetStatus(StartOfRound __instance, bool __runOriginal) { if (__runOriginal) { LobbyControl.CanModifyLobby = true; } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")] [HarmonyPriority(0)] private static void ReopenSteamLobby(StartOfRound __instance, bool __runOriginal) { if (!__runOriginal) { return; } LobbyControl.Log.LogDebug((object)"Lobby can be re-opened"); LobbyControl.CanModifyLobby = true; if (LobbyControl.PluginConfig.SteamLobby.AutoLobby.Value) { Object.FindObjectOfType<QuickMenuManager>().inviteFriendsTextAlpha.alpha = 1f; GameNetworkManager instance = GameNetworkManager.Instance; if (instance.currentLobby.HasValue) { instance.SetLobbyJoinable(true); } } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")] private static void ResetDcFlags(StartOfRound __instance, ulong clientId, int assignedPlayerObjectId) { PlayerControllerB val = __instance.allPlayerScripts[assignedPlayerObjectId]; val.disconnectedMidGame = false; val.DisablePlayerModel(((Component)val).gameObject, true, true); } } [HarmonyPatch] internal class SavePatches { [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")] private static bool PreventSave(GameNetworkManager __instance) { if (LobbyControl.CanSave && __instance.isHostingGame) { ES3.Save<bool>("LC_SavingMethod", LobbyControl.AutoSaveEnabled, __instance.currentSaveFileName); } return LobbyControl.CanSave; } [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")] private static bool PreventSaveFileReset(GameNetworkManager __instance) { return LobbyControl.CanSave; } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Start")] private static void ReadCustomLobbyStatus(StartOfRound __instance, bool __runOriginal) { if (__runOriginal && ((NetworkBehaviour)__instance).IsServer) { LobbyControl.AutoSaveEnabled = (LobbyControl.CanSave = ES3.Load<bool>("LC_SavingMethod", GameNetworkManager.Instance.currentSaveFileName, true)); } } } [HarmonyPatch] internal class TerminalPatch { private const string COMMAND = "\n\n>LOBBY [command] (lobby name)\ntype lobby help for more info.\n\n"; [HarmonyPatch(typeof(Terminal), "Start")] [HarmonyPrefix] private static void StartPatch(ref TerminalNodesList ___terminalNodes) { OverrideTerminalNodes(___terminalNodes); } private static void OverrideTerminalNodes(TerminalNodesList terminalNodes) { OverrideHelpTerminalNode(terminalNodes); } private static void OverrideHelpTerminalNode(TerminalNodesList terminalNodes) { TerminalNode val = null; TerminalKeyword[] allKeywords = terminalNodes.allKeywords; foreach (TerminalKeyword val2 in allKeywords) { if (val2.word == "other") { val = val2.specialKeywordResult; } } if (val != null) { string displayText = val.displayText; string text = displayText.Replace("\n\n>LOBBY [command] (lobby name)\ntype lobby help for more info.\n\n", "").Trim(); text = ((!GameNetworkManager.Instance.isHostingGame) ? (text + "\n\n") : (text + "\n\n>LOBBY [command] (lobby name)\ntype lobby help for more info.\n\n")); val.displayText = text; } } [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] [HarmonyPrefix] private static bool ParsePlayerSentencePatch(ref Terminal __instance, ref TerminalNode __result, bool __runOriginal) { if (!__runOriginal) { return false; } List<string> list = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Split(' ', 3).ToList(); while (list.Count < 3) { list.Add(""); } string[] array = list.ToArray(); if (CommandManager.TryExecuteCommand(array, out var terminalNode)) { if ((Object)(object)terminalNode == (Object)null) { __result = CreateTerminalNode("Error: terminalNode is null!\n\n"); return false; } __result = terminalNode; return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(Terminal), "QuitTerminal")] private static void QuitTerminalPatch() { CommandManager.OnTerminalQuit(); } [HarmonyPatch(typeof(StartOfRound), "OnLocalDisconnect")] [HarmonyPrefix] private static void OnLocalDisconnectPatch() { CommandManager.OnLocalDisconnect(); } internal static TerminalNode CreateTerminalNode(string message, bool clearPreviousText = true) { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); val.displayText = message; val.clearPreviousText = clearPreviousText; val.maxCharactersToType = 50; return val; } } [HarmonyPatch] internal class TransparentPlayerFix { private static readonly HashSet<int> ToRespawn = new HashSet<int>(); private static uint? _killPlayerID; private static uint? _revivePlayerID; private static uint? _sendNewValuesID; [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")] [HarmonyPriority(800)] private static void OnPlayerDCPatch(StartOfRound __instance, int playerObjectNumber, ulong clientId) { if (!LobbyControl.PluginConfig.InvisiblePlayer.Enabled.Value) { return; } PlayerControllerB val = __instance.allPlayerScripts[playerObjectNumber]; if (!StartOfRound.Instance.inShipPhase) { LobbyControl.Log.LogWarning((object)("Player " + val.playerUsername + " disconnected while playing!")); if (((NetworkBehaviour)__instance).IsServer) { LobbyControl.Log.LogInfo((object)("Player " + val.playerUsername + " added to the list of Respawnables")); ToRespawn.Add(playerObjectNumber); } LobbyControl.Log.LogDebug((object)("Model of player " + val.playerUsername + " has been re-enabled")); val.DisablePlayerModel(((Component)val).gameObject, true, true); } } [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "OnLocalDisconnect")] private static void ClearDc() { ToRespawn.Clear(); } internal static void Init() { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown if (!_killPlayerID.HasValue) { MethodInfo methodInfo = AccessTools.Method(typeof(PlayerControllerB), "KillPlayerClientRpc", (Type[])null, (Type[])null); Utils.TryGetRpcID(methodInfo, out var rpcID); _killPlayerID = rpcID; } if (!_revivePlayerID.HasValue) { MethodInfo methodInfo2 = AccessTools.Method(typeof(StartOfRound), "Debug_ReviveAllPlayersClientRpc", (Type[])null, (Type[])null); Utils.TryGetRpcID(methodInfo2, out var rpcID2); _revivePlayerID = rpcID2; } if (!_sendNewValuesID.HasValue) { MethodInfo methodInfo3 = AccessTools.Method(typeof(PlayerControllerB), "SendNewPlayerValuesServerRpc", (Type[])null, (Type[])null); Utils.TryGetRpcID(methodInfo3, out var rpcID3); _sendNewValuesID = rpcID3; MethodInfo methodInfo4 = AccessTools.Method(typeof(PlayerControllerB), $"__rpc_handler_{rpcID3}", (Type[])null, (Type[])null); MethodInfo methodInfo5 = AccessTools.Method(typeof(TransparentPlayerFix), "RespawnDcPlayer", (Type[])null, (Type[])null); LobbyControl._harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void RespawnDcPlayer(NetworkBehaviour target, __RpcParams rpcParams) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invali