Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LobbyImprovements REPO v1.2.6
BepInEx/plugins/LobbyImprovements/uk.1a3.lobbyimprovements.dll
Decompiled a month agousing 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<string, Dictionary<string, string>> nameGuids = new Dictionary<string, Dictionary<string, string>>(); 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<Camera>(); 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<Light>(); 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<Dictionary<string, Dictionary<string, string>>>(text) ?? new Dictionary<string, Dictionary<string, string>>(); } GameObject gameObject = ((Component)LevelGenerator.Instance.LevelParent.GetComponentInChildren<StartRoom>()).gameObject; PhysGrabObject[] array = Object.FindObjectsOfType<PhysGrabObject>(); for (int i = 0; i < array.Length; i++) { array[i].DestroyPhysGrabObject(); } Light[] componentsInChildren = ((Component)gameObject.transform).GetComponentsInChildren<Light>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Renderer[] componentsInChildren2 = ((Component)gameObject.transform).GetComponentsInChildren<Renderer>(); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Canvas[] componentsInChildren3 = ((Component)gameObject.transform.Find("Truck/Truck Run")).GetComponentsInChildren<Canvas>(); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } componentsInChildren = ((Component)PlayerAvatar.instance).GetComponentsInChildren<Light>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } componentsInChildren2 = ((Component)PlayerAvatar.instance).GetComponentsInChildren<Renderer>(); 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<GameObject> 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<GameObject>)(object)((IEnumerable<PrefabRef>)x.spawnObjects).FirstOrDefault((Func<PrefabRef, bool>)((PrefabRef o) => !((PrefabRef<GameObject>)(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<Item> source = (from x in Resources.FindObjectsOfTypeAll<Item>() where Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)x.prefab).Prefab) select x).ToList(); yield return ((MonoBehaviour)this).StartCoroutine(TakeScreenshotsCoroutine((from x in source orderby ((Object)x).name select ((PrefabRef<GameObject>)(object)x.prefab).Prefab).Distinct().ToArray(), "Items", "Items")); ScreenshotEnd(); } internal IEnumerator TakeScreenshotsOfModules() { screenshotType = ScreenshotTypes.Modules; ScreenshotStart(); yield return (object)new WaitForSeconds(2f); List<Level> levels = (from x in Resources.FindObjectsOfTypeAll<Level>() 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<GameObject>)(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<GameObject>)(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<GameObject>)(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<GameObject>)(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<GameObject>)(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<ValuableObject> 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<GameObject>)(object)x).Prefab.GetComponent<ValuableObject>()).Concat(from item in Resources.FindObjectsOfTypeAll<ValuableObject>() 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<Collider>(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<Renderer>(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<string, string>(); } 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<GameObject>(module, Vector3.zero, Quaternion.identity); yield return null; bool useCollisionsForBounds = false; GameObject boundsObject = moduleObject; switch (ssType) { case "Enemies": { Enemy componentInChildren = moduleObject.GetComponentInChildren<Enemy>(); 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<EnemyElsa>().visualsTransform).gameObject; } else if (((Object)module).name == "Enemy - Oogly") { boundsObject = ((Component)((Component)componentInChildren).gameObject.GetComponent<EnemyOogly>().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<Rigidbody>(); if (Object.op_Implicit((Object)(object)component3)) { component3.useGravity = false; component3.velocity = Vector3.zero; component3.constraints = (RigidbodyConstraints)126; } PhysGrabObjectImpactDetector component4 = moduleObject.GetComponent<PhysGrabObjectImpactDetector>(); 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<ItemCartCannonMain>(); 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<PhysGrabObject>(); foreach (PhysGrabObject val in array) { if (!val.hasHinge) { val.DestroyPhysGrabObject(); } } break; } case "Valuables": { Rigidbody component = moduleObject.GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.useGravity = false; component.velocity = Vector3.zero; component.constraints = (RigidbodyConstraints)126; } PhysGrabObjectImpactDetector component2 = moduleObject.GetComponent<PhysGrabObjectImpactDetector>(); 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<string> modDevSteamIDs = new List<string>(2) { "76561198286895332", "76561199523762804" }; internal static Dictionary<string, Dictionary<string, RoleDisplay>> validRoles = new Dictionary<string, Dictionary<string, RoleDisplay>>(); internal static readonly Harmony harmony = new Harmony("uk.1a3.lobbyimprovements"); private static bool initialized; internal static ConfigEntry<bool> cosmeticMoneyRewardPublic; internal static ConfigEntry<bool> cosmeticMoneyRewardPrivate; internal static ConfigEntry<bool> cosmeticMoneyRewardMatchmaking; internal static ConfigEntry<bool> debugConsole; internal static ConfigEntry<KeyboardShortcut> debugConsoleKeybind; internal static ConfigEntry<bool> moonPhaseUIEnabled; internal static ConfigEntry<bool> splashScreenUIEnabled; internal static ConfigEntry<bool> singleplayerLobbyMenu; internal static ConfigEntry<bool> mainMenuOverhaulEnabled; internal static ConfigEntry<string> playerRoleSelected; internal static ConfigEntry<bool> saveDeleteEnabled; internal static ConfigEntry<int> saveFileMaxAmount; internal static ConfigEntry<bool> savePublicEnabled; internal static ConfigEntry<bool> saveMatchmakingEnabled; internal static ConfigEntry<bool> 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<bool>("Cosmetics", "Money Reward (Private)", true, "[Host] Should the money reward from cosmetic tokens be enabled in private lobbies?"); cosmeticMoneyRewardMatchmaking = StaticConfig.Bind<bool>("Cosmetics", "Money Reward (Matchmaking)", true, "[Host] Should the money reward from cosmetic tokens be enabled in random matchmaking lobbies?"); cosmeticMoneyRewardPublic = StaticConfig.Bind<bool>("Cosmetics", "Money Reward (Public)", true, "[Host] Should the money reward from cosmetic tokens be enabled in public lobbies?"); debugConsole = StaticConfig.Bind<bool>("Debug Console", "Enabled", false, "Enables the vanilla debug console."); debugConsoleKeybind = StaticConfig.Bind<KeyboardShortcut>("Debug Console", "Keybind", new KeyboardShortcut((KeyCode)96, Array.Empty<KeyCode>()), (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<bool>("Fast Startup", "Moon Phase", true, "Should the moon phase animation be shown?"); splashScreenUIEnabled = StaticConfig.Bind<bool>("Fast Startup", "Splash Screen", true, "Should the splash screen be shown?"); mainMenuOverhaulEnabled = StaticConfig.Bind<bool>("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<bool>("Saves", "Deletion", true, "[Host] Should saves be automatically deleted when everyone dies?"); saveFileMaxAmount = StaticConfig.Bind<int>("Saves", "Max Amount", 10, new ConfigDescription("What is the max amount of save files? 0 = Unlimited", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); savePublicEnabled = StaticConfig.Bind<bool>("Saves", "Public Lobbies", true, "[Host] Should public lobbies be saved?"); savePublicEnabled.SettingChanged += delegate { PublicLobbySaves.ToggleLobbyTypeSaving((LobbyTypes)1, savePublicEnabled.Value || mainMenuOverhaulEnabled.Value); }; saveMatchmakingEnabled = StaticConfig.Bind<bool>("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<bool>("Singleplayer", "Lobby Menu", false, "[Host] Should the lobby menu be enabled in singleplayer?"); testerOverlayEnabled = StaticConfig.Bind<bool>("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<string>("Name Prefix", "Selected", "none", new ConfigDescription("Which role would you like to use?", (AcceptableValueBase)null, Array.Empty<object>())); 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<bool, string[]>)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<ObjectScreenshotTaker>(); } 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<bool, string, string[], List<string>>)delegate(bool isDebugConsole, string partial, string[] args) { List<string> source = new List<string> { "enemies", "items", "modules", "valuables" }; return (args.Length > 1) ? new List<string>() : source.Where((string g) => args.Length == 0 || g.ToLower().StartsWith(args[0].ToLower())).ToList(); }, (Func<bool>)(() => 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<object>()); __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<string> 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<MenuPage>(); 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", "<u><b>", "</b></u>"); 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 <NewGame_Internal>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<string>)null); }, scrollView, Vector2.zero)).rectTransform; } internal void <NewGame_Internal>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<string>)null); } internal RectTransform <LoadGame_Internal>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<string>)null); }, scrollView, Vector2.zero)).rectTransform; } internal void <LoadGame_Internal>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<string>)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<MenuPageSaves>() : null); if (obj == null) { MenuPage parentPage2 = __instance.parentPage; if (parentPage2 == null) { obj = null; } else { MenuPage pageUnderThisPage = parentPage2.pageUnderThisPage; obj = ((pageUnderThisPage != null) ? ((Component)pageUnderThisPage).GetComponent<MenuPageSaves>() : 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<string>)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<MenuPageSaves>() : null); if (obj == null) { MenuPage parentPage2 = __instance.parentPage; if (parentPage2 == null) { obj = null; } else { MenuPage pageUnderThisPage = parentPage2.pageUnderThisPage; obj = ((pageUnderThisPage != null) ? ((Component)pageUnderThisPage).GetComponent<MenuPageSaves>() : 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<string>)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<TextMeshProUGUI>() : null); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).GetComponent<LocalizationChangedEvent>()); ((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<TextMeshProUGUI>() : null); if (Object.op_Implicit((Object)(object)val2)) { Object.Destroy((Object)(object)((Component)val2).GetComponent<LocalizationChangedEvent>()); ((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<TextMeshProUGUI>() : null); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).GetComponent<LocalizationChangedEvent>()); ((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<MenuPageRegions>().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<MenuPageServerList>(); 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<MenuButton>() : null); } MenuButton val = (MenuButton)obj2; if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val.buttonText).GetComponent<LocalizationChangedEvent>()); ((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<string, List<string>> userRoles { get; set; } = new Dictionary<string, List<string>>(); public Dictionary<string, Dictionary<string, RoleDisplay>> validRoles { get; set; } = new Dictionary<string, Dictionary<string, RoleDisplay>>(); } [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<string> localRoles = new List<string>(); public static Dictionary<string, List<string>> playerRoles = new Dictionary<string, List<string>>(); 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<string> val = null; if ((int)www.result == 1) { try { PlayerRolesResponse playerRolesResponse = JsonConvert.DeserializeObject<PlayerRolesResponse>(www.downloadHandler.text); bool flag = false; foreach (KeyValuePair<string, Dictionary<string, RoleDisplay>> validRole in playerRolesResponse.validRoles) { if (!flag) { if (!PluginLoader.validRoles.TryGetValue(validRole.Key, out var value)) { flag = true; } else { foreach (KeyValuePair<string, RoleDisplay> 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<string> 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<string>(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<string>("Name Prefix", "Selected", "none", new ConfigDescription("Which role would you like to use?", (AcceptableValueBase)(object)val, Array.Empty<object>())); 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<MenuPlayerListed>(); 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<PlayerAvatar, MenuSliderPlayerMicGain> 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, object>)(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<string> 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<string>(); } 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, object>)(object)playerAvatar.photonView.Owner.CustomProperties).ContainsKey((object)PlayerRoles_SteamManager.playerRolesProperty)) { text = (string)playerAvatar.photonView.Owner.CustomProperties[(object)PlayerRoles_SteamManager.playerRolesProperty]; } List<string> 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<string, RoleDisplay> 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<MenuPageSaves>() : 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<MenuPageSaves>() : 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<MenuPageServerListCreateNew>(); 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<MenuPageServerListCreateNew>(); 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<User, User>(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) { } } }