using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using LobbyImprovements.Patches; using MenuLib; using MenuLib.MonoBehaviors; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Photon.Pun; using Photon.Realtime; using Steamworks; using Steamworks.Data; using TMPro; using UnityEngine; using UnityEngine.Networking; [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: AssemblyCompany("uk.1a3.lobbyimprovements")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.6.0")] [assembly: AssemblyInformationalVersion("1.2.6+c89e677ed758b56b87a1b75acac56a2fd30b0dd9")] [assembly: AssemblyProduct("LobbyImprovements")] [assembly: AssemblyTitle("uk.1a3.lobbyimprovements")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LobbyImprovements { public class ObjectScreenshotTaker : MonoBehaviour { private enum ScreenshotTypes { None, Modules, Enemies, Items, Valuables } private readonly string SavePath = "Screenshots"; private readonly string ImageMapFileName = "images.json"; internal static ObjectScreenshotTaker instance; internal bool isTakingScreenshots; private Camera ScreenshotCamera; private Light ScreenshotLight; private GameObject moduleObject; private RenderTexture renderTexture; private Texture2D screenshot; private Color? ambientLight; private ScreenshotTypes screenshotType; private Dictionary> nameGuids = new Dictionary>(); private void Awake() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_00fb: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)instance)) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } instance = this; if ((Object)(object)ScreenshotCamera == (Object)null) { ScreenshotCamera = ((Component)this).gameObject.AddComponent(); ScreenshotCamera.CopyFrom(Camera.main); ((Object)ScreenshotCamera).name = "ScreenshotCamera"; ScreenshotCamera.cullingMask = -4129; ScreenshotCamera.farClipPlane = 2000f; ((Behaviour)ScreenshotCamera).enabled = false; ScreenshotCamera.clearFlags = (CameraClearFlags)2; ScreenshotCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); } if ((Object)(object)ScreenshotLight == (Object)null) { Light spotlight = PlayerAvatar.instance.flashlightController.spotlight; GameObject val = new GameObject("ScreenshotLight"); ScreenshotLight = val.AddComponent(); ScreenshotLight.type = spotlight.type; ScreenshotLight.color = spotlight.color; ScreenshotLight.intensity = spotlight.intensity; ScreenshotLight.range = 100f; ScreenshotLight.spotAngle = 100f; ScreenshotLight.shadows = spotlight.shadows; ScreenshotLight.cookie = spotlight.cookie; ScreenshotLight.cookieSize = spotlight.cookieSize; ScreenshotLight.renderMode = spotlight.renderMode; ((Behaviour)ScreenshotLight).enabled = false; } if (!Directory.Exists(SavePath)) { Directory.CreateDirectory(SavePath); } string path = Path.Combine(SavePath, ImageMapFileName); if (File.Exists(path)) { string text = File.ReadAllText(path); nameGuids = JsonConvert.DeserializeObject>>(text) ?? new Dictionary>(); } GameObject gameObject = ((Component)LevelGenerator.Instance.LevelParent.GetComponentInChildren()).gameObject; PhysGrabObject[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { array[i].DestroyPhysGrabObject(); } Light[] componentsInChildren = ((Component)gameObject.transform).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Renderer[] componentsInChildren2 = ((Component)gameObject.transform).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Canvas[] componentsInChildren3 = ((Component)gameObject.transform.Find("Truck/Truck Run")).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } componentsInChildren = ((Component)PlayerAvatar.instance).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } componentsInChildren2 = ((Component)PlayerAvatar.instance).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } } private void OnDestroy() { PluginLoader.StaticLogger.LogInfo((object)"[ModuleScreenshotTaker] Destroying..."); if (Object.op_Implicit((Object)(object)ScreenshotLight)) { Object.Destroy((Object)(object)((Component)ScreenshotLight).gameObject); } } private void ScreenshotStart() { isTakingScreenshots = true; PlayerAvatar.instance.flashlightController.hideFlashlight = true; PluginLoader.StaticLogger.LogInfo((object)"[ModuleScreenshotTaker] Starting"); } private void ScreenshotEnd() { if (Object.op_Implicit((Object)(object)ScreenshotLight)) { ((Behaviour)ScreenshotLight).enabled = false; } PlayerAvatar.instance.flashlightController.hideFlashlight = false; ambientLight = null; EnvironmentDirector.Instance.DarkAdaptationLerp = ((!FlashlightController.Instance.LightActive) ? 0.01f : 0.99f); isTakingScreenshots = false; PluginLoader.StaticLogger.LogInfo((object)"[ModuleScreenshotTaker] Finished"); if (Object.op_Implicit((Object)(object)ScreenshotLight)) { Object.Destroy((Object)(object)((Component)ScreenshotLight).gameObject); } Object.Destroy((Object)(object)((Component)this).gameObject); } internal IEnumerator TakeScreenshotsOfEnemies() { screenshotType = ScreenshotTypes.Enemies; ScreenshotStart(); yield return (object)new WaitForSeconds(2f); List source = (from x in EnemyDirector.instance.enemiesDifficulty1.Concat(EnemyDirector.instance.enemiesDifficulty2).Concat(EnemyDirector.instance.enemiesDifficulty3) where Object.op_Implicit((Object)(object)x) && !((Object)x).name.Contains("Enemy Group - ") select ((PrefabRef)(object)((IEnumerable)x.spawnObjects).FirstOrDefault((Func)((PrefabRef o) => !((PrefabRef)(object)o).PrefabName.Contains("Director"))))?.Prefab into x where Object.op_Implicit((Object)(object)x) select x).ToList(); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in source.Distinct() orderby ((Object)x).name select x).ToArray(), "Enemies", "Enemies")); ScreenshotEnd(); } internal IEnumerator TakeScreenshotsOfItems() { screenshotType = ScreenshotTypes.Items; ScreenshotStart(); yield return (object)new WaitForSeconds(2f); List source = (from x in Resources.FindObjectsOfTypeAll() where Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)((PrefabRef)(object)x.prefab).Prefab) select x).ToList(); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in source orderby ((Object)x).name select ((PrefabRef)(object)x.prefab).Prefab).Distinct().ToArray(), "Items", "Items")); ScreenshotEnd(); } internal IEnumerator TakeScreenshotsOfModules() { screenshotType = ScreenshotTypes.Modules; ScreenshotStart(); yield return (object)new WaitForSeconds(2f); List levels = (from x in Resources.FindObjectsOfTypeAll() where Object.op_Implicit((Object)(object)x) select x).ToList(); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in (from x in levels.SelectMany((Level x) => x.StartRooms) select ((PrefabRef)(object)x).Prefab).Distinct() orderby ((Object)x).name select x).ToArray(), "StartRoom", "Modules")); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in (from x in levels.SelectMany((Level x) => x.ModulesNormal1.Concat(x.ModulesNormal2).Concat(x.ModulesNormal3)) select ((PrefabRef)(object)x).Prefab).Distinct() orderby ((Object)x).name select x).ToArray(), "Normal", "Modules")); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in (from x in levels.SelectMany((Level x) => x.ModulesPassage1.Concat(x.ModulesPassage2).Concat(x.ModulesPassage3)) select ((PrefabRef)(object)x).Prefab).Distinct() orderby ((Object)x).name select x).ToArray(), "Passage", "Modules")); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in (from x in levels.SelectMany((Level x) => x.ModulesDeadEnd1.Concat(x.ModulesDeadEnd2).Concat(x.ModulesDeadEnd3)) select ((PrefabRef)(object)x).Prefab).Distinct() orderby ((Object)x).name select x).ToArray(), "DeadEnd", "Modules")); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in (from x in levels.SelectMany((Level x) => x.ModulesExtraction1.Concat(x.ModulesExtraction2).Concat(x.ModulesExtraction3)) select ((PrefabRef)(object)x).Prefab).Distinct() orderby ((Object)x).name select x).ToArray(), "Extraction", "Modules")); ScreenshotEnd(); } internal IEnumerator TakeScreenshotsOfValuables() { screenshotType = ScreenshotTypes.Valuables; ScreenshotStart(); yield return (object)new WaitForSeconds(2f); List source = (from x in (from x in RunManager.instance.levels.SelectMany((Level x) => x.ValuablePresets.SelectMany((LevelValuables p) => p.tiny.Concat(p.small).Concat(p.medium).Concat(p.big) .Concat(p.wide) .Concat(p.tall) .Concat(p.veryTall))) select ((PrefabRef)(object)x).Prefab.GetComponent()).Concat(from item in Resources.FindObjectsOfTypeAll() where ((Object)item).name.StartsWith("Enemy Valuable - ") || ((Object)item).name.StartsWith("Surplus Valuable - ") select item) where Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)((Component)x).gameObject) select x).ToList(); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in source orderby ((Object)x).name select ((Component)x).gameObject).Distinct().ToArray(), "Valuables", "Valuables")); ScreenshotEnd(); } private Bounds CalculateBounds(GameObject go, bool useColliders = false) { //IL_00e4: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (useColliders) { Collider[] array = (from r in go.GetComponentsInChildren(true) where r.enabled && ((Component)r).gameObject.activeInHierarchy && !r.isTrigger select r).ToArray(); if (array.Length != 0) { Bounds bounds = array[0].bounds; for (int num = 1; num < array.Length; num++) { ((Bounds)(ref bounds)).Encapsulate(array[num].bounds); } return bounds; } } Renderer[] array2 = (from r in go.GetComponentsInChildren(true) where r.enabled && ((Component)r).gameObject.activeInHierarchy select r).ToArray(); if (array2.Length != 0) { Bounds bounds2 = array2[0].bounds; for (int num2 = 1; num2 < array2.Length; num2++) { ((Bounds)(ref bounds2)).Encapsulate(array2[num2].bounds); } return bounds2; } PluginLoader.StaticLogger.LogWarning((object)("No renderers found for " + ((Object)go).name)); return new Bounds(go.transform.position, Vector3.one); } private IEnumerator TakeScreenshotsCoroutine(GameObject[] modules, string category, string ssType) { if (!Directory.Exists(SavePath + "/" + ssType)) { Directory.CreateDirectory(SavePath + "/" + ssType); } bool updatedNameGuids = false; foreach (GameObject module in modules) { if (!Object.op_Implicit((Object)(object)module)) { continue; } string fileNameRaw = ((Object)module).name; if (ssType == "Enemies") { fileNameRaw = ((Object)module).name.Replace("Enemy - ", ""); } else if (ssType == "Modules") { fileNameRaw = Regex.Replace(((Object)module).name, " - [0-9]+ - ", " - "); } string fileName = SavePath + "/" + ssType + "/" + fileNameRaw + ".png"; if (File.Exists(fileName)) { continue; } if (!nameGuids.ContainsKey(ssType)) { nameGuids[ssType] = new Dictionary(); } if (nameGuids[ssType].TryGetValue(fileNameRaw.ToLower(), out var value)) { string text = SavePath + "/" + ssType + "/" + value + ".png"; if (File.Exists(text)) { continue; } fileName = text; } else if (SteamApps.CurrentBetaName == "tester") { string text2 = Guid.NewGuid().ToString(); string text3 = SavePath + "/" + ssType + "/" + text2 + ".png"; while (File.Exists(text3)) { text2 = Guid.NewGuid().ToString(); text3 = SavePath + "/" + ssType + "/" + text2 + ".png"; } fileName = text3; nameGuids[ssType][fileNameRaw.ToLower()] = text2; updatedNameGuids = true; } if (ssType == "Valuables" && ((Object)module).name.StartsWith("Surplus Valuable - ")) { Time.timeScale = 0f; } moduleObject = Object.Instantiate(module, Vector3.zero, Quaternion.identity); yield return null; bool useCollisionsForBounds = false; GameObject boundsObject = moduleObject; switch (ssType) { case "Enemies": { Enemy componentInChildren = moduleObject.GetComponentInChildren(); if (componentInChildren != null) { componentInChildren.Freeze(7f); } if (((Object)module).name == "Enemy - Bomb Thrower") { boundsObject = ((Component)componentInChildren.Rigidbody).gameObject; } else if (((Object)module).name == "Enemy - Elsa") { boundsObject = ((Component)((Component)componentInChildren).gameObject.GetComponent().visualsTransform).gameObject; } else if (((Object)module).name == "Enemy - Oogly") { boundsObject = ((Component)((Component)componentInChildren).gameObject.GetComponent().visualTransform).gameObject; } if (((Object)module).name != "Enemy - Beamer" && ((Object)module).name != "Enemy - Shadow" && ((Object)module).name != "Enemy - Slow Walker" && ((Object)module).name != "Enemy - Upscream") { useCollisionsForBounds = true; } if (((Object)module).name == "Enemy - Bomb Thrower" || ((Object)module).name == "Enemy - Floater" || ((Object)module).name == "Enemy - Runner" || ((Object)module).name == "Enemy - Slow Walker" || ((Object)module).name == "Enemy - Tumbler") { yield return (object)new WaitForSeconds(1f); } else if (((Object)module).name == "Enemy - Hidden" || ((Object)module).name == "Enemy - Hunter" || ((Object)module).name == "Enemy - Oogly") { yield return (object)new WaitForSeconds(5f); } break; } case "Items": { Rigidbody component3 = moduleObject.GetComponent(); if (Object.op_Implicit((Object)(object)component3)) { component3.useGravity = false; component3.velocity = Vector3.zero; component3.constraints = (RigidbodyConstraints)126; } PhysGrabObjectImpactDetector component4 = moduleObject.GetComponent(); if (Object.op_Implicit((Object)(object)component4) && !component4.particleDisable) { component4.particleDisable = true; } if (((Object)module).name == "Item Cart Cannon" || ((Object)module).name == "Item Cart Laser") { ItemCartCannonMain component5 = moduleObject.GetComponent(); if (component5 != null) { ItemBattery battery = component5.battery; if (battery != null) { BatteryVisualLogic batteryVisualLogic = battery.batteryVisualLogic; if (batteryVisualLogic != null) { ((Component)batteryVisualLogic).gameObject.SetActive(false); } } } } useCollisionsForBounds = true; if (((Object)module).name == "Item Melee Baseball Bat" || ((Object)module).name == "Item Melee Frying Pan" || ((Object)module).name == "Item ReviveItem" || ((Object)module).name.StartsWith("Item Vehicle Semiscooter") || ((Object)module).name.StartsWith("Item WalkieTalkie")) { yield return (object)new WaitForSeconds(1f); } break; } case "Modules": { PhysGrabObject[] array = Object.FindObjectsOfType(); foreach (PhysGrabObject val in array) { if (!val.hasHinge) { val.DestroyPhysGrabObject(); } } break; } case "Valuables": { Rigidbody component = moduleObject.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.useGravity = false; component.velocity = Vector3.zero; component.constraints = (RigidbodyConstraints)126; } PhysGrabObjectImpactDetector component2 = moduleObject.GetComponent(); if (Object.op_Implicit((Object)(object)component2) && !component2.particleDisable) { component2.particleDisable = true; } if (((Object)module).name == "Valuable Gumball") { useCollisionsForBounds = true; } break; } } Bounds val2 = CalculateBounds(boundsObject, useCollisionsForBounds); float num = Mathf.Max(new float[3] { ((Bounds)(ref val2)).size.x, ((Bounds)(ref val2)).size.y, ((Bounds)(ref val2)).size.z }); ScreenshotCamera.orthographic = !((Object)module).name.StartsWith("Enemy Valuable - "); ScreenshotCamera.orthographicSize = num * 0.8f; Vector3 val3 = new Vector3(1f, 1f, -1f); Vector3 val4 = ((Vector3)(ref val3)).normalized; switch (ssType) { case "Enemies": val4 = Vector3.forward; break; case "Items": if (((Object)module).name.StartsWith("Item Upgrade ") || ((Object)module).name.StartsWith("Item ReviveItem") || ((Object)module).name.StartsWith("Item WalkieTalkie")) { val3 = new Vector3(1f, 1f, 1f); val4 = ((Vector3)(ref val3)).normalized; } break; case "Valuables": val3 = new Vector3(1f, 1f, 1f); val4 = ((Vector3)(ref val3)).normalized; break; } float num2 = 1f; if (ssType == "Items") { num2 = 0.75f; } float num3 = num * num2; ((Component)ScreenshotCamera).transform.position = ((Bounds)(ref val2)).center + val4 * num3; ((Component)ScreenshotCamera).transform.LookAt(((Bounds)(ref val2)).center); if (Object.op_Implicit((Object)(object)ScreenshotLight)) { ((Component)ScreenshotLight).transform.position = ((Bounds)(ref val2)).center + val4 * num3; ((Component)ScreenshotLight).transform.LookAt(((Bounds)(ref val2)).center); } if (ssType != "Modules") { if (Object.op_Implicit((Object)(object)ScreenshotLight)) { if (ssType == "Valuables" && (((Object)module).name == "Valuable Goblet" || ((Object)module).name == "Valuable GoldFish" || ((Object)module).name == "Valuable GoldTooth" || ((Object)module).name == "Valuable Piano" || ((Object)module).name == "Valuable SilverFish" || ((Object)module).name == "Valuable Trophy" || ((Object)module).name == "Valuable Wizard Griffin Statue" || ((Object)module).name == "Valuable Wizard Master Potion" || ((Object)module).name == "Valuable Wizard Sword")) { ((Behaviour)ScreenshotLight).enabled = true; } else { ((Behaviour)ScreenshotLight).enabled = false; } } if ((ssType == "Enemies" && ((Object)module).name == "Enemy - Gnome") || (ssType == "Items" && ((Object)module).name == "Item Duck Bucket")) { ambientLight = new Color(0.5f, 0.5f, 0.5f); } else { ambientLight = new Color(1f, 1f, 1f); } RenderSettings.ambientLight = ambientLight.Value; } yield return (object)new WaitForEndOfFrame(); TakeScreenshot(fileName); PluginLoader.StaticLogger.LogDebug((object)("Screenshot saved: " + fileNameRaw + " (" + Path.GetFileName(fileName) + ")")); Object.Destroy((Object)(object)moduleObject); if (Time.timeScale == 0f) { Time.timeScale = 1f; } } if (updatedNameGuids) { string contents = JsonConvert.SerializeObject((object)nameGuids, (Formatting)1); File.WriteAllText(Path.Combine(SavePath, ImageMapFileName), contents); } } private void TakeScreenshot(string filePath) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) renderTexture = new RenderTexture(1920, 1920, 32, (RenderTextureFormat)0); ScreenshotCamera.targetTexture = renderTexture; ScreenshotCamera.Render(); RenderTexture.active = renderTexture; screenshot = new Texture2D(((Texture)renderTexture).width, ((Texture)renderTexture).height, (TextureFormat)4, false); screenshot.ReadPixels(new Rect(0f, 0f, (float)((Texture)renderTexture).width, (float)((Texture)renderTexture).height), 0, 0); screenshot.Apply(); byte[] bytes = ImageConversion.EncodeToPNG(screenshot); File.WriteAllBytes(filePath, bytes); ScreenshotCamera.targetTexture = null; RenderTexture.active = null; Object.Destroy((Object)(object)renderTexture); Object.Destroy((Object)(object)screenshot); } private void LateUpdate() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (isTakingScreenshots && ambientLight.HasValue) { RenderSettings.ambientLight = ambientLight.Value; } } } [BepInPlugin("uk.1a3.lobbyimprovements", "LobbyImprovements", "1.2.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class PluginLoader : BaseUnityPlugin { internal static List modDevSteamIDs = new List(2) { "76561198286895332", "76561199523762804" }; internal static Dictionary> validRoles = new Dictionary>(); internal static readonly Harmony harmony = new Harmony("uk.1a3.lobbyimprovements"); private static bool initialized; internal static ConfigEntry cosmeticMoneyRewardPublic; internal static ConfigEntry cosmeticMoneyRewardPrivate; internal static ConfigEntry cosmeticMoneyRewardMatchmaking; internal static ConfigEntry debugConsole; internal static ConfigEntry debugConsoleKeybind; internal static ConfigEntry moonPhaseUIEnabled; internal static ConfigEntry splashScreenUIEnabled; internal static ConfigEntry singleplayerLobbyMenu; internal static ConfigEntry mainMenuOverhaulEnabled; internal static ConfigEntry playerRoleSelected; internal static ConfigEntry saveDeleteEnabled; internal static ConfigEntry saveFileMaxAmount; internal static ConfigEntry savePublicEnabled; internal static ConfigEntry saveMatchmakingEnabled; internal static ConfigEntry testerOverlayEnabled; internal static bool mainMenuOverhaul; internal static ManualLogSource StaticLogger { get; private set; } internal static ConfigFile StaticConfig { get; private set; } private void Awake() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Expected O, but got Unknown if (initialized) { return; } initialized = true; StaticLogger = ((BaseUnityPlugin)this).Logger; StaticConfig = ((BaseUnityPlugin)this).Config; cosmeticMoneyRewardPrivate = StaticConfig.Bind("Cosmetics", "Money Reward (Private)", true, "[Host] Should the money reward from cosmetic tokens be enabled in private lobbies?"); cosmeticMoneyRewardMatchmaking = StaticConfig.Bind("Cosmetics", "Money Reward (Matchmaking)", true, "[Host] Should the money reward from cosmetic tokens be enabled in random matchmaking lobbies?"); cosmeticMoneyRewardPublic = StaticConfig.Bind("Cosmetics", "Money Reward (Public)", true, "[Host] Should the money reward from cosmetic tokens be enabled in public lobbies?"); debugConsole = StaticConfig.Bind("Debug Console", "Enabled", false, "Enables the vanilla debug console."); debugConsoleKeybind = StaticConfig.Bind("Debug Console", "Keybind", new KeyboardShortcut((KeyCode)96, Array.Empty()), (ConfigDescription)null); debugConsoleKeybind.SettingChanged += delegate { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)DebugConsoleUI.instance)) { DebugConsoleUI instance = DebugConsoleUI.instance; KeyboardShortcut value = debugConsoleKeybind.Value; int num; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0) { num = 96; } else { value = debugConsoleKeybind.Value; num = (int)((KeyboardShortcut)(ref value)).MainKey; } instance.toggleKey = (KeyCode)num; } }; moonPhaseUIEnabled = StaticConfig.Bind("Fast Startup", "Moon Phase", true, "Should the moon phase animation be shown?"); splashScreenUIEnabled = StaticConfig.Bind("Fast Startup", "Splash Screen", true, "Should the splash screen be shown?"); mainMenuOverhaulEnabled = StaticConfig.Bind("Main Menu", "Improved Layout", false, "Improved layout for the main menu to reduce clicks."); if (Chainloader.PluginInfos.ContainsKey("nickklmao.menulib")) { mainMenuOverhaulEnabled.SettingChanged += delegate { PublicLobbySaves.ToggleLobbyTypeSaving((LobbyTypes)1, savePublicEnabled.Value || mainMenuOverhaulEnabled.Value); PublicLobbySaves.ToggleLobbyTypeSaving((LobbyTypes)2, saveMatchmakingEnabled.Value || mainMenuOverhaulEnabled.Value); }; try { harmony.PatchAll(typeof(MenuPageV2)); } catch (Exception ex) { StaticLogger.LogError((object)("MenuPageV2 Patch Failed: " + ex)); } } else if (mainMenuOverhaulEnabled.Value) { StaticLogger.LogWarning((object)"The 'Improved Layout' of the main menu requires the MenuLib mod. Please install it if you wish to use that feature."); } saveDeleteEnabled = StaticConfig.Bind("Saves", "Deletion", true, "[Host] Should saves be automatically deleted when everyone dies?"); saveFileMaxAmount = StaticConfig.Bind("Saves", "Max Amount", 10, new ConfigDescription("What is the max amount of save files? 0 = Unlimited", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); savePublicEnabled = StaticConfig.Bind("Saves", "Public Lobbies", true, "[Host] Should public lobbies be saved?"); savePublicEnabled.SettingChanged += delegate { PublicLobbySaves.ToggleLobbyTypeSaving((LobbyTypes)1, savePublicEnabled.Value || mainMenuOverhaulEnabled.Value); }; saveMatchmakingEnabled = StaticConfig.Bind("Saves", "Random Lobbies", false, "[Host] Should random matchmaking lobbies be saved?"); saveMatchmakingEnabled.SettingChanged += delegate { PublicLobbySaves.ToggleLobbyTypeSaving((LobbyTypes)2, savePublicEnabled.Value || mainMenuOverhaulEnabled.Value); }; singleplayerLobbyMenu = StaticConfig.Bind("Singleplayer", "Lobby Menu", false, "[Host] Should the lobby menu be enabled in singleplayer?"); testerOverlayEnabled = StaticConfig.Bind("Tester Overlay", "Enabled", false, "Should the tester overlay be shown?"); testerOverlayEnabled.SettingChanged += delegate { if (!Debug.isDebugBuild && Object.op_Implicit((Object)(object)DebugCommandHandler.instance)) { DebugCommandHandler.instance.debugOverlay = testerOverlayEnabled.Value; } }; try { harmony.PatchAll(typeof(PlayerRoles_SteamManager)); } catch (Exception ex2) { StaticLogger.LogError((object)("PlayerRoles Patch Failed: " + ex2)); if (playerRoleSelected == null) { playerRoleSelected = StaticConfig.Bind("Name Prefix", "Selected", "none", new ConfigDescription("Which role would you like to use?", (AcceptableValueBase)null, Array.Empty())); playerRoleSelected.SettingChanged += delegate { PlayerRoles_SteamManager.WorldSpaceUIParent_UpdatePlayerName(PlayerAvatar.instance); if (GameManager.Multiplayer()) { PlayerRoles_SemiFunc.PhotonSetCustomProperty(PhotonNetwork.LocalPlayer, PlayerRoles_SteamManager.playerRolesProperty, playerRoleSelected.Value); } }; } } try { harmony.PatchAll(typeof(ChatCommands)); } catch (Exception ex3) { StaticLogger.LogError((object)("ChatCommands Patch Failed: " + ex3)); } try { harmony.PatchAll(typeof(CosmeticPatches)); } catch (Exception ex4) { StaticLogger.LogError((object)("CosmeticPatches Patch Failed: " + ex4)); } try { harmony.PatchAll(typeof(FastStartup)); } catch (Exception ex5) { StaticLogger.LogError((object)("FastStartup Patch Failed: " + ex5)); } try { harmony.PatchAll(typeof(MenuPageLobbySP)); } catch (Exception ex6) { StaticLogger.LogError((object)("MenuPageLobbySP Patch Failed: " + ex6)); } try { harmony.PatchAll(typeof(PublicLobbySaves)); } catch (Exception ex7) { StaticLogger.LogError((object)("PublicLobbySaves Patch Failed: " + ex7)); } try { harmony.PatchAll(typeof(ServerListSearch)); } catch (Exception ex8) { StaticLogger.LogError((object)("ServerListSearch Patch Failed: " + ex8)); } try { harmony.PatchAll(typeof(TesterOverlayPatches)); } catch (Exception ex9) { StaticLogger.LogError((object)("TesterOverlay Patch Failed: " + ex9)); } StaticLogger.LogInfo((object)"Patches Loaded"); } } internal static class MyPluginInfo { public const string PLUGIN_GUID = "uk.1a3.lobbyimprovements"; public const string PLUGIN_NAME = "LobbyImprovements"; public const string PLUGIN_VERSION = "1.2.6"; } } namespace LobbyImprovements.Patches { [HarmonyPatch] public class ChatCommands { [HarmonyPatch(typeof(DebugCommandHandler), "Start")] [HarmonyPostfix] [HarmonyWrapSafe] private static void DebugCommandHandler_Start() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown if (!Debug.isDebugBuild) { DebugCommandHandler.instance.debugOverlay = PluginLoader.testerOverlayEnabled.Value; } DebugCommandHandler.instance.Register(new ChatCommand("screenshot", "Screenshot all enemies, items, modules, or valuables in the current room.", (Action)delegate(bool isDebugConsole, string[] args) { //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) if (!Object.op_Implicit((Object)(object)ObjectScreenshotTaker.instance)) { new GameObject("ObjectScreenshotTaker") { hideFlags = (HideFlags)61 }.AddComponent(); } switch (string.Join(' ', args).ToLower()) { case "enemies": if (!ObjectScreenshotTaker.instance.isTakingScreenshots) { ((MonoBehaviour)ObjectScreenshotTaker.instance).StartCoroutine(ObjectScreenshotTaker.instance.TakeScreenshotsOfEnemies()); DebugCommandHandler.instance.CommandSuccessEffect(); return; } break; case "items": if (!ObjectScreenshotTaker.instance.isTakingScreenshots) { ((MonoBehaviour)ObjectScreenshotTaker.instance).StartCoroutine(ObjectScreenshotTaker.instance.TakeScreenshotsOfItems()); DebugCommandHandler.instance.CommandSuccessEffect(); return; } break; case "modules": if (!ObjectScreenshotTaker.instance.isTakingScreenshots) { ((MonoBehaviour)ObjectScreenshotTaker.instance).StartCoroutine(ObjectScreenshotTaker.instance.TakeScreenshotsOfModules()); DebugCommandHandler.instance.CommandSuccessEffect(); return; } break; case "valuables": if (!ObjectScreenshotTaker.instance.isTakingScreenshots) { ((MonoBehaviour)ObjectScreenshotTaker.instance).StartCoroutine(ObjectScreenshotTaker.instance.TakeScreenshotsOfValuables()); DebugCommandHandler.instance.CommandSuccessEffect(); return; } break; } DebugCommandHandler.instance.CommandFailedEffect(); }, (Func>)delegate(bool isDebugConsole, string partial, string[] args) { List source = new List { "enemies", "items", "modules", "valuables" }; return (args.Length > 1) ? new List() : source.Where((string g) => args.Length == 0 || g.ToLower().StartsWith(args[0].ToLower())).ToList(); }, (Func)(() => SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsRecording()), true)); } [HarmonyPatch(typeof(SemiFunc), "DebugTester")] [HarmonyPostfix] [HarmonyWrapSafe] private static void SemiFunc_DebugTester(ref bool __result) { if (PluginLoader.debugConsole.Value) { __result = true; } } [HarmonyPatch(typeof(DebugConsoleUI), "Awake")] [HarmonyPostfix] [HarmonyWrapSafe] private static void DebugConsoleUI_Awake(DebugConsoleUI __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = PluginLoader.debugConsoleKeybind.Value; KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey; if ((int)mainKey != 0 && (int)mainKey != 96) { __instance.toggleKey = mainKey; } } [HarmonyPatch(typeof(ItemWalkieBox), "OutOfStore")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool ItemWalkieBox_OutOfStore(ItemWalkieBox __instance) { if (Object.op_Implicit((Object)(object)ObjectScreenshotTaker.instance) && ObjectScreenshotTaker.instance.isTakingScreenshots) { __instance.walkiesSpawned = true; return false; } return true; } } [HarmonyPatch] public class CosmeticPatches { [HarmonyPatch(typeof(CosmeticShopMachine), "UpdateState")] [HarmonyPrefix] [HarmonyWrapSafe] private static void CosmeticShopMachine_UpdateState(CosmeticShopMachine __instance, ref State _state) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown if ((int)_state != 5) { return; } LobbyTypes lobbyType = GameManager.instance.lobbyType; switch ((int)lobbyType) { case 0: if (!PluginLoader.cosmeticMoneyRewardPrivate.Value) { break; } return; case 2: if (!PluginLoader.cosmeticMoneyRewardMatchmaking.Value) { break; } return; case 1: if (PluginLoader.cosmeticMoneyRewardPublic.Value) { return; } break; } _state = (State)0; } [HarmonyPatch(typeof(CosmeticShopMachine), "UpdateStateRPC")] [HarmonyPrefix] [HarmonyWrapSafe] private static void CosmeticShopMachine_UpdateStateRPC(CosmeticShopMachine __instance, ref State _state, PhotonMessageInfo _info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (SemiFunc.MasterOnlyRPC(_info) && (int)_state == 0 && (int)__instance.stateCurrent == 4 && (Object)(object)__instance.interactingPlayer == (Object)(object)SemiFunc.PlayerGetLocal()) { CosmeticTokenUI.instance.Setup(); } } } [HarmonyPatch] public class FastStartup { [HarmonyPatch(typeof(MoonUI), "Check")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MoonUI_Check(MoonUI __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if (!PluginLoader.moonPhaseUIEnabled.Value && (int)__instance.state > 0) { __instance.skip = true; __instance.SetState((State)8); } } [HarmonyPatch(typeof(SemiFunc), "SplashScreenSkip")] [HarmonyPrefix] [HarmonyWrapSafe] private static void SemiFunc_SplashScreenSkip(ref bool forceSkip) { if (!PluginLoader.splashScreenUIEnabled.Value) { forceSkip = true; } } [HarmonyPatch(typeof(NetworkManager), "Update")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool NetworkManager_Update(NetworkManager __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)GameDirector.instance.currentState != 1 || LoadingUI.instance.levelAnimationCompleted || Object.op_Implicit((Object)(object)MenuPagePassword.instance)) { return true; } if (GameManager.instance.gameMode == 1 && PhotonNetwork.IsMasterClient && !__instance.LoadingDone && __instance.instantiatedPlayerAvatars >= PhotonNetwork.CurrentRoom.PlayerCount) { ((MonoBehaviourPun)__instance).photonView.RPC("AllPlayerSpawnedRPC", (RpcTarget)3, Array.Empty()); __instance.LoadingDone = true; } __instance.loadingScreenTimer += Time.deltaTime; if (__instance.loadingScreenTimer >= 25f) { LoadingUI.instance.stuckActive = true; if (SemiFunc.InputDown((InputKey)6)) { __instance.TriggerLeavePhotonRoomForcedStuckInLoading(); } } return false; } [HarmonyPatch(typeof(GameDirector), "SetStart")] [HarmonyPostfix] [HarmonyWrapSafe] private static void GameDirector_SetStart() { if (Object.op_Implicit((Object)(object)NetworkManager.instance) && Object.op_Implicit((Object)(object)LoadingUI.instance)) { NetworkManager.instance.loadingScreenTimer = 10f; } } } [HarmonyPatch] public class MenuPageLobbySP { [HarmonyPatch(typeof(DataDirector), "SaveDeleteCheck")] [HarmonyPrefix] [HarmonyPriority(800)] private static bool DataDirector_SaveDeleteCheck() { return PluginLoader.saveDeleteEnabled.Value; } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] [HarmonyPrefix] [HarmonyWrapSafe] private static void RunManager_ChangeLevel_Prefix(RunManager __instance, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType = (ChangeLevelType)0) { if (PluginLoader.singleplayerLobbyMenu.Value && !SemiFunc.IsMultiplayer() && (SemiFunc.MenuLevel() || SemiFunc.IsMasterClientOrSingleplayer()) && !__instance.restarting && _levelFailed && __instance.levelArena.Contains(__instance.levelCurrent)) { __instance.debugLevel = __instance.levelLobbyMenu; PluginLoader.StaticLogger.LogInfo((object)"Setting debug level"); } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] [HarmonyPostfix] [HarmonyWrapSafe] private static void RunManager_ChangeLevel_Postfix(RunManager __instance, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType = (ChangeLevelType)0) { if (!SemiFunc.IsMultiplayer() && __instance.gameOver && (Object)(object)__instance.debugLevel == (Object)(object)__instance.levelLobbyMenu) { __instance.debugLevel = null; PluginLoader.StaticLogger.LogInfo((object)"Resetting debug level"); } } [HarmonyPatch(typeof(SemiFunc), "MenuActionSingleplayerGame")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool SemiFunc_MenuActionSingleplayerGame(string saveFileName, List saveFileBackups) { if (!PluginLoader.singleplayerLobbyMenu.Value) { return true; } RunManager.instance.ResetProgress(); GameManager.instance.SetConnectRandom(false); if (saveFileName != null) { PluginLoader.StaticLogger.LogInfo((object)"Loading save"); SemiFunc.SaveFileLoad(saveFileName, saveFileBackups); } else { SemiFunc.SaveFileCreate(); } RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)3); return false; } [HarmonyPatch(typeof(MenuPageLobby), "Awake")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageLobby_Awake(MenuPageLobby __instance) { if (SemiFunc.IsMultiplayer()) { return true; } MenuPageLobby.instance = __instance; __instance.menuPage = ((Component)__instance).GetComponent(); TextMeshProUGUI roomNameText = __instance.roomNameText; string cloudRegion = PhotonNetwork.CloudRegion; Room currentRoom = PhotonNetwork.CurrentRoom; ((TMP_Text)roomNameText).text = cloudRegion + " " + ((currentRoom != null) ? currentRoom.Name : null); ((TMP_Text)__instance.chatPromptText).text = InputManager.instance.InputDisplayReplaceTags("Press [chat] to use commands", "", ""); return false; } [HarmonyPatch(typeof(MenuPageLobby), "Start")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageLobby_Start(MenuPageLobby __instance) { if (SemiFunc.IsMultiplayer()) { return true; } ((Component)__instance.inviteButton).gameObject.SetActive(false); return false; } [HarmonyPatch(typeof(MenuPageLobby), "ButtonStart")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageLobby_ButtonStart(MenuPageLobby __instance) { if (SemiFunc.IsMultiplayer() || __instance.joiningPlayer) { return true; } SteamManager.instance.LockLobby(); DataDirector.instance.RunsPlayedAdd(); if (RunManager.instance.loadLevel == 0) { RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)1); } else { RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)5); } return false; } } [HarmonyPatch] public class MenuPageV2 { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action <>9__1_6; public static ScrollViewBuilderDelegate <>9__1_2; public static Action <>9__2_6; public static ScrollViewBuilderDelegate <>9__2_2; internal RectTransform b__1_2(Transform scrollView) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) return ((REPOElement)MenuAPI.CreateREPOButton("Public (Random)", (Action)delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PublicLobbySaves.publicSavesMenuOpen = false; GameManager.instance.matchmakingMode = (RandomMatchmakingModes)1; SemiFunc.MenuActionRandomMatchmaking((string)null, (List)null); }, scrollView, Vector2.zero)).rectTransform; } internal void b__1_6() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PublicLobbySaves.publicSavesMenuOpen = false; GameManager.instance.matchmakingMode = (RandomMatchmakingModes)1; SemiFunc.MenuActionRandomMatchmaking((string)null, (List)null); } internal RectTransform b__2_2(Transform scrollView) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) return ((REPOElement)MenuAPI.CreateREPOButton("Public (Random)", (Action)delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PublicLobbySaves.publicSavesMenuOpen = false; GameManager.instance.matchmakingMode = (RandomMatchmakingModes)1; SemiFunc.MenuActionRandomMatchmaking(StatsManager.instance.saveFileCurrent, (List)null); }, scrollView, Vector2.zero)).rectTransform; } internal void b__2_6() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PublicLobbySaves.publicSavesMenuOpen = false; GameManager.instance.matchmakingMode = (RandomMatchmakingModes)1; SemiFunc.MenuActionRandomMatchmaking(StatsManager.instance.saveFileCurrent, (List)null); } } private static MenuPageIndex regionsPreviousPage = (MenuPageIndex)11; internal static void NewGame_Internal(MenuButton __instance) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown MenuPage parentPage = __instance.parentPage; object obj = ((parentPage != null) ? ((Component)parentPage).GetComponent() : null); if (obj == null) { MenuPage parentPage2 = __instance.parentPage; if (parentPage2 == null) { obj = null; } else { MenuPage pageUnderThisPage = parentPage2.pageUnderThisPage; obj = ((pageUnderThisPage != null) ? ((Component)pageUnderThisPage).GetComponent() : null); } } MenuPageSaves menuPageSaves = (MenuPageSaves)obj; if (Object.op_Implicit((Object)(object)menuPageSaves) && menuPageSaves.maxSaveFiles > 0 && menuPageSaves.saveFiles.Count >= menuPageSaves.maxSaveFiles) { MenuManager.instance.PageCloseAllAddedOnTop(); MenuManager.instance.PagePopUp("Save file limit reached", Color.red, $"You can only have {menuPageSaves.maxSaveFiles} save files at a time. Please delete some save files to make room for new ones.", "OK", true); return; } REPOPopupPage repoPage = MenuAPI.CreateREPOPopupPage(__instance.menuButtonPopUp?.headerText, false, true, 1.5f, (Vector2?)Vector2.zero); repoPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Private", (Action)delegate { PublicLobbySaves.publicSavesMenuOpen = false; MenuPageSaves obj4 = menuPageSaves; if (obj4 != null) { obj4.OnNewGame(); } }, scrollView, Vector2.zero)).rectTransform), 0f, 0f); repoPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Public (Server List)", (Action)delegate { PublicLobbySaves.publicSavesMenuOpen = true; MenuPageSaves obj4 = menuPageSaves; if (obj4 != null) { obj4.OnNewGame(); } }, scrollView, Vector2.zero)).rectTransform), 0f, 0f); REPOPopupPage obj2 = repoPage; object obj3 = <>c.<>9__1_2; if (obj3 == null) { ScrollViewBuilderDelegate val = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Public (Random)", (Action)delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PublicLobbySaves.publicSavesMenuOpen = false; GameManager.instance.matchmakingMode = (RandomMatchmakingModes)1; SemiFunc.MenuActionRandomMatchmaking((string)null, (List)null); }, scrollView, Vector2.zero)).rectTransform; <>c.<>9__1_2 = val; obj3 = (object)val; } obj2.AddElementToScrollView((ScrollViewBuilderDelegate)obj3, 0f, 0f); repoPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Back", (Action)delegate { repoPage.ClosePage(false); }, scrollView, Vector2.zero)).rectTransform), 0f, 0f); repoPage.OpenPage(false); } internal static void LoadGame_Internal(MenuButton __instance) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown MenuPage parentPage = __instance.parentPage; object obj = ((parentPage != null) ? ((Component)parentPage).GetComponent() : null); if (obj == null) { MenuPage parentPage2 = __instance.parentPage; if (parentPage2 == null) { obj = null; } else { MenuPage pageUnderThisPage = parentPage2.pageUnderThisPage; obj = ((pageUnderThisPage != null) ? ((Component)pageUnderThisPage).GetComponent() : null); } } MenuPageSaves menuPageSaves = (MenuPageSaves)obj; REPOPopupPage repoPage = MenuAPI.CreateREPOPopupPage(__instance.menuButtonPopUp?.headerText, false, true, 1.5f, (Vector2?)Vector2.zero); repoPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Private", (Action)delegate { PublicLobbySaves.publicSavesMenuOpen = false; MenuPageSaves obj4 = menuPageSaves; if (obj4 != null) { obj4.OnLoadGame(); } }, scrollView, Vector2.zero)).rectTransform), 0f, 0f); repoPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Public (Server List)", (Action)delegate { PublicLobbySaves.publicSavesMenuOpen = true; MenuPageSaves obj4 = menuPageSaves; if (obj4 != null) { obj4.OnLoadGame(); } }, scrollView, Vector2.zero)).rectTransform), 0f, 0f); REPOPopupPage obj2 = repoPage; object obj3 = <>c.<>9__2_2; if (obj3 == null) { ScrollViewBuilderDelegate val = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Public (Random)", (Action)delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PublicLobbySaves.publicSavesMenuOpen = false; GameManager.instance.matchmakingMode = (RandomMatchmakingModes)1; SemiFunc.MenuActionRandomMatchmaking(StatsManager.instance.saveFileCurrent, (List)null); }, scrollView, Vector2.zero)).rectTransform; <>c.<>9__2_2 = val; obj3 = (object)val; } obj2.AddElementToScrollView((ScrollViewBuilderDelegate)obj3, 0f, 0f); repoPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Back", (Action)delegate { repoPage.ClosePage(false); }, scrollView, Vector2.zero)).rectTransform), 0f, 0f); repoPage.OpenPage(false); } [HarmonyPatch(typeof(MenuPageMain), "Start")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MenuPageMain_Start(MenuPageMain __instance) { PluginLoader.mainMenuOverhaul = PluginLoader.mainMenuOverhaulEnabled.Value; if (PluginLoader.mainMenuOverhaul) { Transform obj = ((Component)__instance.rectTransform).transform.Find("Buttons/Menu Button - Private Game/ButtonText"); TextMeshProUGUI val = ((obj != null) ? ((Component)obj).GetComponent() : null); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).GetComponent()); ((TMP_Text)val).text = "Host Game"; } Transform obj2 = ((Component)__instance.rectTransform).transform.Find("Buttons/Menu Button - Public Game/ButtonText"); TextMeshProUGUI val2 = ((obj2 != null) ? ((Component)obj2).GetComponent() : null); if (Object.op_Implicit((Object)(object)val2)) { Object.Destroy((Object)(object)((Component)val2).GetComponent()); ((TMP_Text)val2).text = "Join Game"; } } } [HarmonyPatch(typeof(MenuPageMain), "ButtonEventHostGame")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageMain_ButtonEventHostGame() { if (!PluginLoader.mainMenuOverhaul) { return true; } SemiFunc.MainMenuSetMultiplayer(); MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)11, false); return false; } [HarmonyPatch(typeof(MenuPageMain), "ButtonEventPlayRandom")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageMain_ButtonEventPlayRandom() { if (!PluginLoader.mainMenuOverhaul) { return true; } MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)16, false); return false; } [HarmonyPatch(typeof(MenuManager), "PageOpen")] [HarmonyPrefix] [HarmonyWrapSafe] private static void MenuManager_PageOpen_Prefix(MenuManager __instance, MenuPage __result, MenuPageIndex menuPageIndex, bool addedPageOnTop = false) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (PluginLoader.mainMenuOverhaul && ((int)menuPageIndex == 11 || (int)menuPageIndex == 16 || (int)menuPageIndex == 14)) { regionsPreviousPage = menuPageIndex; } } [HarmonyPatch(typeof(MenuManager), "PageOpen")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MenuManager_PageOpen(MenuManager __instance, MenuPage __result, MenuPageIndex menuPageIndex, bool addedPageOnTop = false) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!PluginLoader.mainMenuOverhaul) { return; } if ((int)menuPageIndex != 11) { if ((int)menuPageIndex != 14) { if ((int)menuPageIndex == 16) { Transform obj = ((Component)__result).transform.Find("Header/Text (TMP)"); TextMeshProUGUI val = ((obj != null) ? ((Component)obj).GetComponent() : null); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).GetComponent()); ((TMP_Text)val).text = "Join Game"; } AddRegionMenuButton(((Component)__result).transform, new Vector2(8f, 8f), (Type)1); } } else { AddRegionMenuButton(((Component)__result).transform, new Vector2(8f, 8f), (Type)1); } } else if (SemiFunc.MainMenuIsMultiplayer()) { AddRegionMenuButton(((Component)__result).transform, new Vector2(520f, 325f), (Type)0); } } private static void AddRegionMenuButton(Transform parent, Vector2 localPosition, Type pageType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) DataDirector.instance.networkRegion = PlayerPrefs.GetString("PUNSelectedRegion", ""); ServerSettings.ResetBestRegionCodeInPreferences(); MenuAPI.CreateREPOButton(GetRegionDisplayName(DataDirector.instance.networkRegion), (Action)delegate { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) MenuManager.instance.PageCloseAll(); ((Component)MenuManager.instance.PageOpen((MenuPageIndex)13, false)).GetComponent().type = pageType; }, parent, localPosition); } private static string GetRegionDisplayName(string regionCode) { return (regionCode?.ToUpper() ?? "") switch { "" => "Best Region", "ASIA" => "Asia", "AU" => "Australia", "CAE" => "Canada East", "CN" => "Chinese Mainland", "EU" => "Europe", "HK" => "Hong Kong", "IN" => "India", "JP" => "Japan", "ZA" => "South Africa", "SA" => "South America", "KR" => "South Korea", "TR" => "Turkey", "UAE" => "United Arab Emirates", "US" => "USA East", "USW" => "USA West", "USSC" => "USA South Central", _ => regionCode?.ToUpper(), }; } private static void RefreshLobbies() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) MenuPageServerList component = ((Component)MenuManager.instance.currentMenuPage).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || !component.receivedList || component.searchInProgress) { return; } foreach (Transform item in component.serverElementParent) { Object.Destroy((Object)(object)((Component)item).gameObject); } component.loadingGraphics.Reset(); component.roomListSearched.Clear(); component.receivedList = false; component.pageMax = 0; component.buttonNext.HideSetInstant(); component.buttonPrevious.HideSetInstant(); ((MonoBehaviour)component).StartCoroutine(component.GetServerList()); } [HarmonyPatch(typeof(MenuPageServerList), "Start")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MenuPageServerList_Start(MenuPageServerList __instance) { if (PluginLoader.mainMenuOverhaul) { Transform obj = ((Component)__instance).transform.Find("Panel/Create New"); object obj2; if (obj == null) { obj2 = null; } else { Transform obj3 = obj.Find("Menu Button - CREATE NEW"); obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent() : null); } MenuButton val = (MenuButton)obj2; if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val.buttonText).GetComponent()); ((TMP_Text)val.buttonText).text = "Refresh"; } } } [HarmonyPatch(typeof(MenuPageServerList), "OnDestroy")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageServerList_OnDestroy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)MenuManager.instance)) { return (int)MenuManager.instance.currentMenuPageIndex != 13; } return true; } [HarmonyPatch(typeof(MenuPageServerList), "ButtonCreateNew")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageServerList_ButtonCreateNew() { if (!PluginLoader.mainMenuOverhaul) { return true; } RefreshLobbies(); return false; } [HarmonyPatch(typeof(MenuPagePublicGameChoice), "ButtonRandomMatchmaking")] [HarmonyPrefix] [HarmonyWrapSafe] private static void MenuPagePublicGameChoice_ButtonRandomMatchmaking() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) GameManager.instance.matchmakingMode = (RandomMatchmakingModes)((PluginLoader.mainMenuOverhaul && PluginLoader.saveMatchmakingEnabled.Value) ? 2 : 0); } [HarmonyPatch(typeof(MenuPagePublicGameChoice), "ExitPage")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPagePublicGameChoice_ExitPage() { if (!PluginLoader.mainMenuOverhaul) { return true; } MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)0, false); return false; } [HarmonyPatch(typeof(MenuPageRegions), "PickRegion")] [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPriority(800)] private static bool MenuPageRegions_PickRegion(MenuPageRegions __instance, string _region) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) PlayerPrefs.SetString("PUNSelectedRegion", _region); PlayerPrefs.Save(); if ((int)regionsPreviousPage == 14) { DataDirector.instance.networkRegion = _region; MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen(regionsPreviousPage, false); return false; } return true; } [HarmonyPatch(typeof(MenuPageRegions), "ExitPage")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageRegions_ExitPage(MenuPageRegions __instance) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!PluginLoader.mainMenuOverhaul) { return true; } MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen(regionsPreviousPage, false); return false; } [HarmonyPatch(typeof(MenuPageRegions), "OnDestroy")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageRegions_OnDestroy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)MenuManager.instance)) { return (int)MenuManager.instance.currentMenuPageIndex != 14; } return true; } [HarmonyPatch(typeof(NetworkManager), "OnDisconnected")] [HarmonyPostfix] [HarmonyWrapSafe] private static void NetworkManager_OnDisconnected(DisconnectCause cause) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)cause == 15) { PlayerPrefs.DeleteKey("PUNSelectedRegion"); PlayerPrefs.Save(); } } } public class RoleDisplay { public string prefix { get; set; } = ""; public string suffix { get; set; } = ""; public string devPrefix { get; set; } = ""; public string devSuffix { get; set; } = ""; } public class PlayerRolesResponse { public Dictionary> userRoles { get; set; } = new Dictionary>(); public Dictionary> validRoles { get; set; } = new Dictionary>(); } [HarmonyPatch] public class PlayerRoles_SteamManager { internal static string playerRolesProperty = "playerNamePrefix"; private static string playerRolesUrl = "https://1a3.uk/api/games/repo/mods/lobbyimprovements/player-roles.json"; private static bool fetchedLocalPlayer; public static List localRoles = new List(); public static Dictionary> playerRoles = new Dictionary>(); private static IEnumerator GetPlayerRoles(string[] steamIds, string logType) { steamIds = (from x in steamIds where Regex.IsMatch(x, "^76[0-9]{15}$") orderby x select x).ToArray(); if (steamIds.Length == 0) { yield break; } string localSteamId = ((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString(); bool includesLocalPlayer = steamIds.Contains(localSteamId); string text = playerRolesUrl + "?context=" + logType + "&self=" + localSteamId + "&" + string.Join("&", steamIds.Select((string id) => "id=" + id)); UnityWebRequest www = UnityWebRequest.Get(text); www.SetRequestHeader("Cache-Control", "no-cache"); yield return www.SendWebRequest(); AcceptableValueList val = null; if ((int)www.result == 1) { try { PlayerRolesResponse playerRolesResponse = JsonConvert.DeserializeObject(www.downloadHandler.text); bool flag = false; foreach (KeyValuePair> validRole in playerRolesResponse.validRoles) { if (!flag) { if (!PluginLoader.validRoles.TryGetValue(validRole.Key, out var value)) { flag = true; } else { foreach (KeyValuePair item in validRole.Value) { if (!value.TryGetValue(item.Key, out var value2) || !(value2.prefix == item.Value.prefix) || !(value2.suffix == item.Value.suffix) || !(value2.devPrefix == item.Value.devPrefix) || !(value2.devSuffix == item.Value.devSuffix)) { flag = true; break; } } } } PluginLoader.validRoles[validRole.Key] = validRole.Value; } if (flag && Object.op_Implicit((Object)(object)GameDirector.instance)) { foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { WorldSpaceUIParent_UpdatePlayerName(player); } } string[] array = steamIds; foreach (string text2 in array) { List value4; if (text2 == localSteamId) { if (playerRolesResponse.userRoles.TryGetValue(text2, out var value3)) { localRoles = value3; PluginLoader.StaticLogger.LogDebug((object)string.Format("[GetPlayerRoles | {0}] {1} has {2} roles: {3}", logType, text2, value3.Count, string.Join(", ", value3))); } else { localRoles.Clear(); PluginLoader.StaticLogger.LogDebug((object)("[GetPlayerRoles | " + logType + "] " + text2 + " has 0 roles")); } } else if (playerRolesResponse.userRoles.TryGetValue(text2, out value4)) { playerRoles[text2] = value4; PluginLoader.StaticLogger.LogDebug((object)string.Format("[GetPlayerRoles | {0}] {1} has {2} roles: {3}", logType, text2, value4.Count, string.Join(", ", value4))); } else { playerRoles.Remove(text2); PluginLoader.StaticLogger.LogDebug((object)("[GetPlayerRoles | " + logType + "] " + text2 + " has 0 roles")); } } if (includesLocalPlayer) { val = new AcceptableValueList(localRoles.Prepend("none").ToArray()); } } catch (JsonException ex) { JsonException ex2 = ex; PluginLoader.StaticLogger.LogWarning((object)("[GetPlayerRoles | " + logType + "] Failed to parse roles: " + ((Exception)(object)ex2).Message)); } } else { PluginLoader.StaticLogger.LogWarning((object)("[GetPlayerRoles | " + logType + "] Failed to fetch roles: " + www.error)); } www.Dispose(); if (!includesLocalPlayer) { yield break; } fetchedLocalPlayer = true; PluginLoader.playerRoleSelected = PluginLoader.StaticConfig.Bind("Name Prefix", "Selected", "none", new ConfigDescription("Which role would you like to use?", (AcceptableValueBase)(object)val, Array.Empty())); PluginLoader.playerRoleSelected.SettingChanged += delegate { WorldSpaceUIParent_UpdatePlayerName(PlayerAvatar.instance); if (GameManager.Multiplayer()) { PlayerRoles_SemiFunc.PhotonSetCustomProperty(PhotonNetwork.LocalPlayer, playerRolesProperty, PluginLoader.playerRoleSelected?.Value); } }; } public static void WorldSpaceUIParent_UpdatePlayerName(PlayerAvatar _player) { if (Object.op_Implicit((Object)(object)_player?.worldSpaceUIPlayerName)) { string prefixStringForPlayer = PlayerRoles_SemiFunc.GetPrefixStringForPlayer(_player, "avatar_nametag"); if (!string.IsNullOrWhiteSpace(prefixStringForPlayer)) { ((TMP_Text)_player.worldSpaceUIPlayerName.text).richText = true; ((TMP_Text)_player.worldSpaceUIPlayerName.text).text = prefixStringForPlayer; } else { ((TMP_Text)_player.worldSpaceUIPlayerName.text).richText = false; ((TMP_Text)_player.worldSpaceUIPlayerName.text).text = _player.playerName; } } } [HarmonyPatch(typeof(SteamManager), "Awake")] [HarmonyPostfix] [HarmonyWrapSafe] private static void SteamManager_Awake(SteamManager __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (SteamClient.IsValid && !fetchedLocalPlayer) { ((MonoBehaviour)__instance).StartCoroutine(GetPlayerRoles(new string[1] { ((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString() }, "self_init")); } } [HarmonyPatch(typeof(SteamManager), "OnLobbyEntered")] [HarmonyPostfix] [HarmonyWrapSafe] private unsafe static void SteamManager_OnLobbyEntered(SteamManager __instance, Lobby _lobby) { string[] array = (from x in ((Lobby)(ref _lobby)).Members select ((object)(*(SteamId*)(&x.Id))/*cast due to .constrained prefix*/).ToString() into x where x != ((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString() select x).ToArray(); if (array.Length != 0) { ((MonoBehaviour)__instance).StartCoroutine(GetPlayerRoles(array, "self_joined")); } } [HarmonyPatch(typeof(SteamManager), "OnLobbyMemberJoined")] [HarmonyPostfix] [HarmonyWrapSafe] private unsafe static void SteamManager_OnLobbyMemberJoined(SteamManager __instance, Lobby _lobby, Friend _friend) { ((MonoBehaviour)__instance).StartCoroutine(GetPlayerRoles(new string[1] { ((object)(*(SteamId*)(&_friend.Id))/*cast due to .constrained prefix*/).ToString() }, "member_joined")); } [HarmonyPatch(typeof(SteamManager), "OnLobbyMemberLeft")] [HarmonyPostfix] [HarmonyWrapSafe] private unsafe static void SteamManager_OnLobbyMemberLeft(Lobby _lobby, Friend _friend) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (playerRoles.ContainsKey(((object)(*(SteamId*)(&_friend.Id))/*cast due to .constrained prefix*/).ToString())) { PluginLoader.StaticLogger.LogDebug((object)$"[playerRoles | SteamManager_OnLobbyMemberLeft] Removing 1 player ({_friend.Id})"); playerRoles.Remove(((object)(*(SteamId*)(&_friend.Id))/*cast due to .constrained prefix*/).ToString()); } } [HarmonyPatch(typeof(SteamManager), "LeaveLobby")] [HarmonyPostfix] [HarmonyWrapSafe] private static void SteamManager_LeaveLobby() { if (playerRoles.Count > 0) { PluginLoader.StaticLogger.LogDebug((object)$"[playerRoles | SteamManager_LeaveLobby] Removing {playerRoles.Count} players"); playerRoles.Clear(); } } [HarmonyPatch(typeof(PlayerAvatar), "Awake")] [HarmonyPostfix] [HarmonyWrapSafe] private static void PlayerAvatar_Awake(PlayerAvatar __instance) { if (SemiFunc.IsMultiplayer() && __instance.isLocal) { PlayerRoles_SemiFunc.PhotonSetCustomProperty(PhotonNetwork.LocalPlayer, playerRolesProperty, PluginLoader.playerRoleSelected?.Value); } } [HarmonyPatch(typeof(MenuPageLobby), "Update")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MenuPageLobby_Update(MenuPageLobby __instance) { foreach (GameObject listObject in __instance.listObjects) { MenuPlayerListed component = listObject.GetComponent(); PlayerAvatar playerAvatar = component.playerAvatar; if (Object.op_Implicit((Object)(object)playerAvatar)) { TextMeshProUGUI playerName = component.playerName; string prefixStringForPlayer = PlayerRoles_SemiFunc.GetPrefixStringForPlayer(playerAvatar, "menu_page_lobby"); if (!string.IsNullOrWhiteSpace(prefixStringForPlayer)) { ((TMP_Text)playerName).richText = true; ((TMP_Text)playerName).text = prefixStringForPlayer; } else { ((TMP_Text)playerName).richText = false; ((TMP_Text)playerName).text = playerAvatar.playerName; } } } } private static IEnumerator DelayedUpdatePauseMenuSliders(MenuPageEsc __instance) { yield return null; foreach (KeyValuePair playerMicGainSlider in __instance.playerMicGainSliders) { PlayerAvatar key = playerMicGainSlider.Key; TextMeshProUGUI elementNameText = playerMicGainSlider.Value.menuSlider.elementNameText; string prefixStringForPlayer = PlayerRoles_SemiFunc.GetPrefixStringForPlayer(key, "menu_page_esc"); if (!string.IsNullOrWhiteSpace(prefixStringForPlayer)) { ((TMP_Text)elementNameText).richText = true; ((TMP_Text)elementNameText).text = prefixStringForPlayer; } else { ((TMP_Text)elementNameText).richText = false; ((TMP_Text)elementNameText).text = key.playerName; } } } [HarmonyPatch(typeof(MenuPageEsc), "PlayerGainSlidersUpdate")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MenuPageEsc_PlayerGainSlidersUpdate(MenuPageEsc __instance) { ((MonoBehaviour)__instance).StartCoroutine(DelayedUpdatePauseMenuSliders(__instance)); } [HarmonyPatch(typeof(WorldSpaceUIParent), "PlayerName")] [HarmonyPostfix] [HarmonyWrapSafe] private static void WorldSpaceUIParent_PlayerName(PlayerAvatar _player) { WorldSpaceUIParent_UpdatePlayerName(_player); } [HarmonyPatch(typeof(MonoBehaviourPunCallbacks), "OnPlayerPropertiesUpdate")] [HarmonyPostfix] [HarmonyWrapSafe] private static void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (!((Dictionary)(object)changedProps).ContainsKey((object)playerRolesProperty)) { return; } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (player.photonView.Owner == targetPlayer) { WorldSpaceUIParent_UpdatePlayerName(player); break; } } } } public class PlayerRoles_SemiFunc { public static List GetPrefixDataForSteamId(string steamId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (steamId == ((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString()) { return PlayerRoles_SteamManager.localRoles; } if (PlayerRoles_SteamManager.playerRoles.TryGetValue(steamId, out var value)) { return value; } return new List(); } public static string GetPrefixStringForPlayer(PlayerAvatar playerAvatar, string contextKey) { //IL_0075: 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) if (!Object.op_Implicit((Object)(object)playerAvatar)) { return null; } string text = null; if (playerAvatar.isLocal) { text = PluginLoader.playerRoleSelected?.Value; } else if (((Dictionary)(object)playerAvatar.photonView.Owner.CustomProperties).ContainsKey((object)PlayerRoles_SteamManager.playerRolesProperty)) { text = (string)playerAvatar.photonView.Owner.CustomProperties[(object)PlayerRoles_SteamManager.playerRolesProperty]; } List prefixDataForSteamId = GetPrefixDataForSteamId(playerAvatar.steamID); bool flag = PluginLoader.modDevSteamIDs.Contains(((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString()); RoleDisplay roleDisplay = null; bool flag2 = false; if (!string.IsNullOrWhiteSpace(text) && PluginLoader.validRoles.TryGetValue(text, out var value)) { roleDisplay = GetContextEntry(value, contextKey); } if (roleDisplay == null && flag && prefixDataForSteamId.Count > 0) { foreach (string item in prefixDataForSteamId) { RoleDisplay contextEntry = GetContextEntry(PluginLoader.validRoles[item], contextKey); if (contextEntry != null && (!string.IsNullOrEmpty(contextEntry.devPrefix) || !string.IsNullOrEmpty(contextEntry.devSuffix))) { roleDisplay = contextEntry; flag2 = true; break; } } } if (roleDisplay == null) { return null; } string text2 = (flag2 ? roleDisplay.devPrefix : roleDisplay.prefix) ?? ""; string text3 = (flag2 ? roleDisplay.devSuffix : roleDisplay.suffix) ?? ""; if (!string.IsNullOrWhiteSpace(text2) || !string.IsNullOrWhiteSpace(text3)) { return text2 + Regex.Replace(playerAvatar.playerName ?? "", "<.*?>", string.Empty) + text3; } return null; } private static RoleDisplay GetContextEntry(Dictionary contextMap, string contextKey) { if (contextMap.TryGetValue(contextKey, out var value) && (!string.IsNullOrEmpty(value.prefix) || !string.IsNullOrEmpty(value.suffix))) { return value; } if (contextMap.TryGetValue("default", out var value2) && (!string.IsNullOrEmpty(value2.prefix) || !string.IsNullOrEmpty(value2.suffix))) { return value2; } return null; } public unsafe static void PhotonSetCustomProperty(Player photonPlayer, object key, object value) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties; Hashtable val = new Hashtable(); DictionaryEntryEnumerator enumerator = customProperties.GetEnumerator(); try { while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext()) { DictionaryEntry current = ((DictionaryEntryEnumerator)(ref enumerator)).Current; val[current.Key] = current.Value; } } finally { ((IDisposable)(*(DictionaryEntryEnumerator*)(&enumerator))/*cast due to .constrained prefix*/).Dispose(); } val[key] = value; photonPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } [HarmonyPatch] public class PublicLobbySaves { internal static bool publicSavesMenuOpen; internal static bool compatNoSaveDelete; public static void ToggleLobbyTypeSaving(LobbyTypes lobbyType, bool state) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)StatsManager.instance)) { if (state && !StatsManager.instance.savedLobbyTypes.Contains(lobbyType)) { StatsManager.instance.savedLobbyTypes.Add(lobbyType); } else if (!state && StatsManager.instance.savedLobbyTypes.Contains(lobbyType)) { StatsManager.instance.savedLobbyTypes.Remove(lobbyType); } } } [HarmonyPatch(typeof(MenuPageServerList), "ButtonCreateNew")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageServerList_ButtonCreateNew(MenuPageServerList __instance) { if (!PluginLoader.savePublicEnabled.Value || PluginLoader.mainMenuOverhaul) { return true; } SemiFunc.MainMenuSetMultiplayer(); publicSavesMenuOpen = true; MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)11, false); return false; } [HarmonyPatch(typeof(MenuPageSaves), "Start")] [HarmonyPostfix] [HarmonyWrapSafe] private static void MenuPageSaves_Start(MenuPageSaves __instance) { if (SemiFunc.MainMenuIsMultiplayer() && !PluginLoader.mainMenuOverhaul) { ((TMP_Text)__instance.gameModeHeader).text = (publicSavesMenuOpen ? "Public Multiplayer" : "Private Multiplayer"); } else { publicSavesMenuOpen = false; } __instance.maxSaveFiles = PluginLoader.saveFileMaxAmount.Value; if (!compatNoSaveDelete && Harmony.HasAnyPatches("com.PxntxrezStudio.nosavedelete")) { compatNoSaveDelete = true; PluginLoader.StaticLogger.LogInfo((object)"Compatibility Enabled: NoSaveDelete"); PluginLoader.harmony.Unpatch((MethodBase)typeof(MenuPageSaves).GetMethod("OnNewGame"), (HarmonyPatchType)1, "com.PxntxrezStudio.nosavedelete"); } } [MethodImpl(MethodImplOptions.NoInlining)] [HarmonyPatch(typeof(MenuButton), "OnSelect")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuButton_OnSelect(MenuButton __instance) { if (__instance.menuButtonPopUp?.headerText == "New Game" && __instance.menuButtonPopUp?.bodyText == "Do you want to start a game?") { if (PluginLoader.mainMenuOverhaul && SemiFunc.MainMenuIsMultiplayer()) { MenuPageV2.NewGame_Internal(__instance); return false; } if (publicSavesMenuOpen) { MenuPage parentPage = __instance.parentPage; MenuPageSaves obj = ((parentPage != null) ? ((Component)parentPage).GetComponent() : null); if (obj != null) { obj.OnNewGame(); } return false; } } if (__instance.menuButtonPopUp?.headerText == "Load save?" && __instance.menuButtonPopUp?.bodyText == "Load this save file?") { if (PluginLoader.mainMenuOverhaul && SemiFunc.MainMenuIsMultiplayer()) { MenuPageV2.LoadGame_Internal(__instance); return false; } if (publicSavesMenuOpen) { MenuPage parentPage2 = __instance.parentPage; MenuPageSaves obj2 = ((parentPage2 != null) ? ((Component)parentPage2).GetComponent() : null); if (obj2 != null) { obj2.OnLoadGame(); } return false; } } return true; } [HarmonyPatch(typeof(MenuPageSaves), "OnNewGame")] [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPriority(800)] private static bool MenuPageSaves_OnNewGame(MenuPageSaves __instance) { if (!publicSavesMenuOpen || __instance.saveFiles.Count >= __instance.maxSaveFiles) { return true; } MenuPage currentMenuPage = MenuManager.instance.currentMenuPage; MenuPageServerListCreateNew component = ((Component)MenuManager.instance.PageOpenOnTop((MenuPageIndex)15)).GetComponent(); component.menuPageParent = currentMenuPage; component.menuTextInput.textCurrent = SteamClient.Name + "'s Lobby"; return false; } [HarmonyPatch(typeof(MenuPageSaves), "OnLoadGame")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageSaves_OnLoadGame(MenuPageSaves __instance) { if (!publicSavesMenuOpen) { return true; } MenuPage currentMenuPage = MenuManager.instance.currentMenuPage; MenuPageServerListCreateNew component = ((Component)MenuManager.instance.PageOpenOnTop((MenuPageIndex)15)).GetComponent(); component.menuPageParent = currentMenuPage; component.menuTextInput.textCurrent = SteamClient.Name + "'s Lobby"; component.saveFileName = __instance.currentSaveFileName; return false; } [HarmonyPatch(typeof(MenuPageServerListCreateNew), "ExitPage")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageServerListCreateNew_ExitPage(MenuPageServerListCreateNew __instance) { if (!publicSavesMenuOpen && !PluginLoader.mainMenuOverhaul) { return true; } MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)11, false); return false; } [HarmonyPatch(typeof(MenuPageSaves), "OnGoBack")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageSaves_OnGoBack(MenuPageSaves __instance) { if (!publicSavesMenuOpen) { return true; } publicSavesMenuOpen = false; MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)14, false); return false; } [HarmonyPatch(typeof(StatsManager), "Awake")] [HarmonyPostfix] [HarmonyWrapSafe] private static void StatsManager_Awake_Postfix(StatsManager __instance) { ToggleLobbyTypeSaving((LobbyTypes)1, PluginLoader.savePublicEnabled.Value || PluginLoader.mainMenuOverhaulEnabled.Value); ToggleLobbyTypeSaving((LobbyTypes)2, PluginLoader.saveMatchmakingEnabled.Value || PluginLoader.mainMenuOverhaulEnabled.Value); } } [HarmonyPatch] public class ServerListSearch { [HarmonyPatch(typeof(MenuPageServerListSearch), "Update")] [HarmonyPrefix] [HarmonyWrapSafe] private static void MenuPageServerListSearch_Update(MenuPageServerListSearch __instance) { if (Input.GetKey((KeyCode)306) && Input.GetKeyDown((KeyCode)118)) { string systemCopyBuffer = GUIUtility.systemCopyBuffer; Match match = Regex.Match(systemCopyBuffer, "steam://joinlobby/\\d+/(\\d+)/\\d+"); if (match.Success) { MenuTextInput menuTextInput = __instance.menuTextInput; menuTextInput.textCurrent += match.Groups[1].Value; } else { MenuTextInput menuTextInput2 = __instance.menuTextInput; menuTextInput2.textCurrent += systemCopyBuffer; } } } [HarmonyPatch(typeof(MenuPageServerList), "SetSearch")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool MenuPageServerList_SetSearch(string _searchString) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(_searchString) && Regex.IsMatch(_searchString, "^[0-9]{17,19}$") && ulong.TryParse(_searchString, out var result)) { if (SteamApps.BuildId <= 18995935) { MenuManager instance = MenuManager.instance; if (instance != null) { instance.PageCloseAll(); } MenuManager instance2 = MenuManager.instance; if (instance2 != null) { instance2.PageOpen((MenuPageIndex)0, false); } } SteamManager.instance.OnGameLobbyJoinRequested(new Lobby(SteamId.op_Implicit(result)), SteamClient.SteamId); return false; } return true; } } [HarmonyPatch] public class TesterOverlayPatches { [HarmonyPatch(typeof(DebugTesterUI), "Start")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool DebugTesterUI_Start(DebugTesterUI __instance) { if (!Debug.isDebugBuild) { return SemiFunc.DebugDev(); } return true; } [HarmonyPatch(typeof(SteamManager), "Awake")] [HarmonyPostfix] [HarmonyWrapSafe] private static void SteamManager_Awake(SteamManager __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)SteamManager.instance != (Object)(object)__instance) && !__instance.developerMode && SteamClient.IsValid && PluginLoader.modDevSteamIDs.Contains(((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString())) { __instance.developerUser = (User)7; __instance.developerMode = true; Debug.Log((object)("DEVELOPER MODE: " + ((object)Unsafe.As(ref __instance.developerUser)/*cast due to .constrained prefix*/).ToString().ToUpper() + " (MOD)")); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }