Decompiled source of FFAArena Lite v1.0.4
BepInEx/plugins/FFAArena_Lite/FFAArena_Lite.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FFAArenaLite.Modules; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FFAArena_Lite")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+88eee74c23ce3135eb65f6847908ec4a40aaa461")] [assembly: AssemblyProduct("FFA Arena Lite")] [assembly: AssemblyTitle("FFAArena_Lite")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [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 FFAArenaLite { [BepInPlugin("com.cheekyentity.ffaarena.lite", "FFA Arena Lite", "1.0.4")] [BepInProcess("MageArena.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.cheekyentity.ffaarena.lite"; public const string PluginName = "FFA Arena Lite"; public const string PluginVersion = "1.0.4"; public static string modsync = "all"; private Harmony _harmony; internal static ManualLogSource Log; internal static ConfigEntry<int> InitialLives; private void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"FFA Arena Lite v1.0.4 loading..."); InitialLives = ((BaseUnityPlugin)this).Config.Bind<int>("FFA", "InitialLives", 3, "Default lives per player in FFA last-player-standing mode."); try { FFALastStand.DefaultLives = InitialLives.Value; } catch { } _harmony = new Harmony("com.cheekyentity.ffaarena.lite"); _harmony.PatchAll(); Log.LogInfo((object)"Harmony patches applied."); } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Harmony patches removed. Goodbye."); } } } } namespace FFAArenaLite.Patches { [HarmonyPatch] public static class EnableMeshRenderersPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("EnableMeshRenderers"); if (type == null) { return null; } return AccessTools.Method(type, "enableRenderers", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(object __instance) { bool flag = FFAMode.IsActive(); try { if (!flag) { try { flag = MainMenuPatch.IsFFASelected(); } catch { } } } catch { } if (!flag) { return true; } try { Component val = (Component)((__instance is Component) ? __instance : null); if ((Object)(object)val == (Object)null) { return true; } int num = 0; int num2 = 0; MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { if (ShouldSkipObject(((Component)val2).gameObject, ((Renderer)val2).sharedMaterials)) { num2++; continue; } ((Renderer)val2).enabled = true; num++; } } SkinnedMeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null)) { if (ShouldSkipObject(((Component)val3).gameObject, ((Renderer)val3).sharedMaterials)) { num2++; continue; } ((Renderer)val3).enabled = true; num++; } } if (num2 > 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"EnableMeshRenderersPatch: enabled={num}, skipped(flag/pole/banner)={num2} under '{((Object)val.gameObject).name}'."); } } return false; } catch (Exception arg) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"EnableMeshRenderersPatch failed, falling back to original: {arg}"); } return true; } } private static bool ShouldSkipObject(GameObject go, Material[] mats) { try { if ((Object)(object)go == (Object)null) { return false; } Type type = AccessTools.TypeByName("FlagController"); if (type != null) { MethodInfo method = typeof(Component).GetMethod("GetComponentInParent", new Type[1] { typeof(Type) }); if (method != null && (Object)/*isinst with value type is only supported in some contexts*/ != (Object)null) { return true; } } if (NameMatchesHeuristic(go.transform)) { return true; } try { if (mats != null) { foreach (Material val in mats) { if (!((Object)(object)val == (Object)null) && StringMatchesHeuristic(((Object)val).name)) { return true; } } } } catch { } } catch { } return false; } private static bool NameMatchesHeuristic(Transform t) { int num = 0; while ((Object)(object)t != (Object)null && num++ < 5) { if (StringMatchesHeuristic(((Object)t).name)) { return true; } t = t.parent; } return false; } private static bool StringMatchesHeuristic(string s) { if (string.IsNullOrEmpty(s)) { return false; } s = s.ToLowerInvariant(); if (!s.Contains("flag") && !s.Contains("pole") && !s.Contains("banner")) { return s.Contains("pennant"); } return true; } } [HarmonyPatch] public static class FlagController_OnStartClient_FFAPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("FlagController"); if (!(type != null)) { return null; } return AccessTools.Method(type, "OnStartClient", (Type[])null, (Type[])null); } private static bool Prefix(object __instance) { try { if (!FFAMode.IsActive() && !MainMenuPatch.IsFFASelected()) { return true; } Component val = (Component)((__instance is Component) ? __instance : null); if (val != null && (Object)(object)val != (Object)null) { Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 != null) { val2.enabled = false; } Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } try { Type type = ((object)val).GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "flagvisual"); FieldInfo fieldInfo2 = AccessTools.Field(type, "FlagAni"); FieldInfo fieldInfo3 = AccessTools.Field(type, "particles"); FieldInfo fieldInfo4 = AccessTools.Field(type, "FlagAudio"); object? obj = fieldInfo?.GetValue(__instance); Renderer val3 = (Renderer)((obj is Renderer) ? obj : null); if (val3 != null) { val3.enabled = false; } object? obj2 = fieldInfo2?.GetValue(__instance); Behaviour val4 = (Behaviour)((obj2 is Behaviour) ? obj2 : null); if (val4 != null) { val4.enabled = false; } if (fieldInfo3?.GetValue(__instance) is ParticleSystem[] array) { ParticleSystem[] array2 = array; foreach (ParticleSystem val5 in array2) { if (!((Object)(object)val5 == (Object)null)) { val5.Stop(true, (ParticleSystemStopBehavior)0); Renderer component2 = ((Component)val5).GetComponent<Renderer>(); if (Object.op_Implicit((Object)(object)component2)) { component2.enabled = false; } } } } object? obj3 = fieldInfo4?.GetValue(__instance); AudioSource val6 = (AudioSource)((obj3 is AudioSource) ? obj3 : null); if (val6 != null) { val6.Stop(); ((Behaviour)val6).enabled = false; } Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer val7 in componentsInChildren) { if ((Object)(object)val7 == (Object)null) { continue; } string text = ((Object)val7).name.ToLowerInvariant(); bool flag = text.Contains("flag") || text.Contains("pole") || text.Contains("banner"); if (!flag) { try { Material[] sharedMaterials = val7.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (flag) { break; } Material val8 = sharedMaterials[j]; if (!((Object)(object)val8 == (Object)null)) { string text2 = ((Object)val8).name.ToLowerInvariant(); if (text2.Contains("flag") || text2.Contains("pole") || text2.Contains("banner")) { flag = true; } } } } catch { } } if (flag) { val7.enabled = false; } } } catch { } try { string text3 = (((Object)(object)val.gameObject != (Object)null) ? ((Object)val.gameObject).name : "<null>"); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("FFA: Neutralized FlagController in OnStartClient on '" + text3 + "'.")); } } catch { } } return false; } catch (Exception arg) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"FFA: FlagController_OnStartClient_FFAPatch failed: {arg}"); } return true; } } } [HarmonyPatch] public static class FlagController_Awake_FFAPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("FlagController"); if (!(type != null)) { return null; } return AccessTools.Method(type, "Awake", (Type[])null, (Type[])null); } private static bool Prefix(object __instance) { try { if (!FFAMode.IsActive() && !MainMenuPatch.IsFFASelected()) { return true; } Component val = (Component)((__instance is Component) ? __instance : null); if (val != null && (Object)(object)val != (Object)null) { Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 != null) { val2.enabled = false; } Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } try { Type type = ((object)val).GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "flagvisual"); FieldInfo fieldInfo2 = AccessTools.Field(type, "FlagAni"); FieldInfo fieldInfo3 = AccessTools.Field(type, "particles"); FieldInfo fieldInfo4 = AccessTools.Field(type, "FlagAudio"); object? obj = fieldInfo?.GetValue(__instance); Renderer val3 = (Renderer)((obj is Renderer) ? obj : null); if (val3 != null) { val3.enabled = false; } object? obj2 = fieldInfo2?.GetValue(__instance); Behaviour val4 = (Behaviour)((obj2 is Behaviour) ? obj2 : null); if (val4 != null) { val4.enabled = false; } if (fieldInfo3?.GetValue(__instance) is ParticleSystem[] array) { ParticleSystem[] array2 = array; foreach (ParticleSystem val5 in array2) { if (!((Object)(object)val5 == (Object)null)) { val5.Stop(true, (ParticleSystemStopBehavior)0); Renderer component2 = ((Component)val5).GetComponent<Renderer>(); if (Object.op_Implicit((Object)(object)component2)) { component2.enabled = false; } } } } object? obj3 = fieldInfo4?.GetValue(__instance); AudioSource val6 = (AudioSource)((obj3 is AudioSource) ? obj3 : null); if (val6 != null) { val6.Stop(); ((Behaviour)val6).enabled = false; } Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer val7 in componentsInChildren) { if ((Object)(object)val7 == (Object)null) { continue; } string text = ((Object)val7).name.ToLowerInvariant(); bool flag = text.Contains("flag") || text.Contains("pole") || text.Contains("banner"); if (!flag) { try { Material[] sharedMaterials = val7.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (flag) { break; } Material val8 = sharedMaterials[j]; if (!((Object)(object)val8 == (Object)null)) { string text2 = ((Object)val8).name.ToLowerInvariant(); if (text2.Contains("flag") || text2.Contains("pole") || text2.Contains("banner")) { flag = true; } } } } catch { } } if (flag) { val7.enabled = false; } } } catch { } try { string text3 = (((Object)(object)val.gameObject != (Object)null) ? ((Object)val.gameObject).name : "<null>"); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("FFA: Neutralized FlagController in Awake on '" + text3 + "'.")); } } catch { } } return false; } catch (Exception arg) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"FFA: FlagController_Awake_FFAPatch failed: {arg}"); } return true; } } } [HarmonyPatch] public static class CastleFlagCapturedNotifier_Start_FFAPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("CastleFlagCapturedNotifier"); if (!(type != null)) { return null; } return AccessTools.Method(type, "StartFlagsShit", (Type[])null, (Type[])null); } private static bool Prefix(object __instance) { try { if (!FFAMode.IsActive()) { return true; } Component val = (Component)((__instance is Component) ? __instance : null); if (val != null && (Object)(object)val != (Object)null) { Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 != null) { val2.enabled = false; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"FFA: Disabled CastleFlagCapturedNotifier component."); } } return false; } catch (Exception arg) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"FFA: CastleFlagCapturedNotifier_Start_FFAPatch failed: {arg}"); } return true; } } } [HarmonyPatch] public static class MagicMissleController_Update_Prefix { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("MagicMissleController"); if (!(type == null)) { return AccessTools.Method(type, "Update", (Type[])null, (Type[])null); } return null; } private static void Prefix(object __instance) { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00ec: Unknown result type (might be due to invalid IL or missing references) try { if (!FFAMode.IsActive()) { return; } Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "MissleTarget"); object? obj = fieldInfo?.GetValue(__instance); if ((Object)((obj is GameObject) ? obj : null) != (Object)null) { return; } object? obj2 = AccessTools.Field(type, "playerOwner")?.GetValue(__instance); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); if ((Object)(object)val == (Object)null) { return; } object obj3 = AccessTools.Field(type, "playerLayer")?.GetValue(__instance); int num2 = ((obj3 is LayerMask val2) ? ((LayerMask)(ref val2)).value : ((obj3 is int num) ? num : (-1))); Vector3 val4 = ((AccessTools.Field(type, "forwardVector")?.GetValue(__instance) is Vector3 val3) ? val3 : Vector3.forward); bool flag = false; try { FieldInfo fieldInfo2 = AccessTools.Field(type, "shotByAi"); if (fieldInfo2 != null) { flag = (bool)fieldInfo2.GetValue(__instance); } } catch { } Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 30f, num2); float num3 = float.MaxValue; GameObject val5 = null; Collider[] array2 = array; GetPlayerGameobject val7 = default(GetPlayerGameobject); foreach (Collider val6 in array2) { if ((Object)(object)val6 == (Object)null) { continue; } GameObject gameObject = ((Component)val6).gameObject; if ((Object)(object)gameObject == (Object)(object)val || (gameObject.TryGetComponent<GetPlayerGameobject>(ref val7) && (Object)(object)val7.player == (Object)(object)val) || (flag && (gameObject.CompareTag("PlayerNpc") || gameObject.CompareTag("Ignorable")))) { continue; } Vector3 val8 = ((Component)val6).transform.position - ((Component)__instance).transform.position; float magnitude = ((Vector3)(ref val8)).magnitude; float num4 = Vector3.Angle(val4, ((Vector3)(ref val8)).normalized); if (!(num4 > 90f)) { float num5 = magnitude + num4 * 0.5f; if (num5 < num3) { num3 = num5; val5 = gameObject; } } } if ((Object)(object)val5 != (Object)null) { fieldInfo?.SetValue(__instance, val5); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)$"MagicMissile FFA target selection error: {arg}"); } } } } [HarmonyPatch] public static class MainMenuPatch { private static int? selectedFFAMapinfo; internal static bool IsFFASelected() { return selectedFFAMapinfo.HasValue; } public static bool ShouldHideTeamUI(object mainMenuInstance) { try { if (FFAMode.IsActive() || IsFFASelected()) { return true; } Type type = mainMenuInstance?.GetType(); GameObject val = null; try { object? obj = AccessTools.Field(type, "InGameLobby")?.GetValue(mainMenuInstance); val = (GameObject)((obj is GameObject) ? obj : null); } catch { } if ((Object)(object)val != (Object)null && MarkerInTransformTree(val.transform)) { return true; } try { Transform[] array = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val2 in array) { if (!((Object)(object)val2 == (Object)null)) { switch (((Object)val2).name) { case "FFA_Medium_Button": case "FFA_Large_Button": case "FreeForAllLabel_Auto": case "EditTeamFlag": return true; } } } } catch { } } catch { } return false; static bool MarkerInTransformTree(Transform root) { if ((Object)(object)root == (Object)null) { return false; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { string name = ((Object)val3).name; if (!string.IsNullOrEmpty(name)) { switch (name) { case "FFA_Medium_Button": case "FFA_Large_Button": case "FreeForAllLabel_Auto": case "EditTeamFlag": return true; } } } } return false; } } internal static bool IsLocalHostOrServer(object mainMenuInstance) { try { Type type = AccessTools.TypeByName("FishNet.Managing.NetworkManager"); if (type != null) { object obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null, null) ?? Object.FindFirstObjectByType(type); if (obj != null) { PropertyInfo propertyInfo = type.GetProperty("IsServer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetProperty("IsHost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (propertyInfo != null) { object value = propertyInfo.GetValue(obj, null); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return true; } } } } } catch { } return false; } internal static Transform FindInactiveTransform(string path) { if (string.IsNullOrEmpty(path)) { return null; } try { string[] array = path.Split('/'); if (array.Length == 0) { return null; } Transform[] array2 = Resources.FindObjectsOfTypeAll<Transform>(); Transform val = null; Transform[] array3 = array2; foreach (Transform val2 in array3) { if ((Object)(object)val2.parent == (Object)null && ((Object)val2).name == array[0]) { val = val2; break; } } if ((Object)(object)val == (Object)null) { return null; } for (int j = 1; j < array.Length; j++) { string text = array[j]; Transform val3 = null; for (int k = 0; k < val.childCount; k++) { Transform child = val.GetChild(k); if ((Object)(object)child != (Object)null && ((Object)child).name == text) { val3 = child; break; } } if ((Object)(object)val3 == (Object)null) { return null; } val = val3; } return val; } catch { return null; } } internal static Button CloneButtonFromPath(string sourcePath, Transform parent, string newName, string label, Action onClick) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown try { Transform val = FindInactiveTransform(sourcePath); if ((Object)(object)val == (Object)null) { return null; } Button component = ((Component)val).GetComponent<Button>(); if ((Object)(object)component == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(((Component)component).gameObject, parent); ((Object)val2).name = newName; val2.SetActive(true); if ((Object)(object)parent != (Object)null) { val2.layer = ((Component)parent).gameObject.layer; } RectTransform component2 = val2.GetComponent<RectTransform>(); if ((Object)(object)component2 != (Object)null) { ((Transform)component2).localScale = Vector3.one; component2.anchoredPosition3D = Vector3.zero; } CanvasGroup component3 = val2.GetComponent<CanvasGroup>(); if ((Object)(object)component3 != (Object)null) { component3.alpha = 1f; component3.interactable = true; component3.blocksRaycasts = true; } Button component4 = val2.GetComponent<Button>(); if ((Object)(object)component4 != (Object)null) { ((UnityEventBase)component4.onClick).RemoveAllListeners(); if (onClick != null) { ((UnityEvent)component4.onClick).AddListener((UnityAction)delegate { onClick(); }); } } Text[] componentsInChildren = val2.GetComponentsInChildren<Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = label; } return component4; } catch { return null; } } [HarmonyPostfix] private static void ActuallyStartGameActually_Postfix(object __instance) { //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) try { Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "pm"); if (fieldInfo == null) { return; } object value = fieldInfo.GetValue(__instance); if (value == null) { return; } FieldInfo fieldInfo2 = AccessTools.Field(value.GetType(), "teamSpawns"); if (fieldInfo2 == null) { return; } object value2 = fieldInfo2.GetValue(value); Type elemType = (fieldInfo2.FieldType.IsArray ? fieldInfo2.FieldType.GetElementType() : null); if (elemType == null) { return; } SpawnService spawnService = new SpawnService(); FieldInfo fieldInfo3 = AccessTools.Field(type, "mapinfo"); if (fieldInfo3 != null) { try { _ = (int)fieldInfo3.GetValue(__instance); } catch { } } if (selectedFFAMapinfo.HasValue) { spawnService.CollectFFASpawnsByMapInfo(selectedFFAMapinfo.Value); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Using FFA custom spawns for mapinfo={selectedFFAMapinfo.Value}."); } } else { spawnService.CollectNeutralSpawns(); } IReadOnlyList<Transform> sourceSpawns = spawnService.GetSpawns(); Type wormholeType = AccessTools.TypeByName("RespawnWormhole"); bool wantWormholes = wormholeType != null && elemType == wormholeType; int desiredLen = 4; Array array; try { array = BuildWormholesFromTransforms(); } catch { array = value2 as Array; } if (array != null) { if (array.Length < desiredLen) { Array array2 = Array.CreateInstance(elemType, desiredLen); for (int i = 0; i < desiredLen; i++) { object value3 = ((i < array.Length) ? array.GetValue(i) : ((array.Length > 0) ? array.GetValue(0) : null)); array2.SetValue(value3, i); } array = array2; } fieldInfo2.SetValue(value, array); } selectedFFAMapinfo = null; try { int num = array?.Length ?? 0; if (num <= 0) { return; } object? value4 = array.GetValue(0); Object val = (Object)((value4 is Object) ? value4 : null); Vector3 val2 = Vector3.zero; string text = string.Empty; Component val3 = (Component)(object)((val is Component) ? val : null); if (val3 != null) { val2 = val3.transform.position; } else { GameObject val4 = (GameObject)(object)((val is GameObject) ? val : null); if (val4 != null) { val2 = val4.transform.position; } } try { Type type2 = ((object)val)?.GetType(); if (type2 != null && type2.Name == "RespawnWormhole") { object? obj3 = AccessTools.Field(type2, "spawnpos")?.GetValue(val); Transform val5 = (Transform)((obj3 is Transform) ? obj3 : null); if ((Object)(object)val5 != (Object)null) { text = $", spawnpos={val5.position}"; } } } catch { } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogDebug((object)string.Format("teamSpawns[0/{0}] type={1} pos={2}{3}", num, (val != (Object)null) ? ((object)val).GetType().Name : "null", val2, text)); } } catch { } Array BuildWormholesFromTransforms() { //IL_0240: 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_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown int num2 = Mathf.Max(desiredLen, sourceSpawns.Count); Array array3 = Array.CreateInstance(elemType, num2); SpawnService.EnsureRuntimeContainer(); GameObject val6 = null; try { val6 = GameObject.Find("FFA_Runtime_SpawnContainer"); } catch { } for (int j = 0; j < num2; j++) { Transform val7 = ((sourceSpawns.Count > 0) ? sourceSpawns[j % sourceSpawns.Count] : null); object obj7 = null; if ((Object)(object)val7 != (Object)null) { if (wantWormholes) { GameObject val8 = null; try { string text2 = $"FFA_Wormhole_{j}"; if ((Object)(object)val6 != (Object)null) { Transform val9 = null; foreach (Transform item in val6.transform) { Transform val10 = item; if ((Object)(object)val10 != (Object)null && ((Object)val10).name == text2) { val9 = val10; break; } } val8 = (((Object)(object)val9 != (Object)null) ? ((Component)val9).gameObject : null); } if ((Object)(object)val8 == (Object)null) { val8 = new GameObject($"FFA_Wormhole_{j}"); if ((Object)(object)val6 != (Object)null) { val8.transform.SetParent(val6.transform, false); } } val8.transform.position = val7.position; MethodInfo method = typeof(GameObject).GetMethod("AddComponent", new Type[1] { typeof(Type) }); Component val11 = (Component)(((object)val8.GetComponent(wormholeType)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if ((Object)(object)val11 != (Object)null) { FieldInfo fieldInfo4 = AccessTools.Field(wormholeType, "spawnpos"); Transform val12 = null; try { object? obj8 = fieldInfo4?.GetValue(val11); val12 = (Transform)((obj8 is Transform) ? obj8 : null); } catch { } if ((Object)(object)val12 == (Object)null) { GameObject val13 = new GameObject("spawnpos"); val13.transform.SetParent(val8.transform, false); val12 = val13.transform; } val12.position = val7.position; fieldInfo4?.SetValue(val11, val12); obj7 = val11; } } catch { } } else { object obj11 = ((val7 != null) ? ((Component)val7).GetComponent(elemType) : null); if (obj11 == null) { obj11 = ((val7 != null) ? ((Component)val7).GetComponentInChildren(elemType, true) : null); } obj7 = obj11; if (obj7 == null && elemType == typeof(Transform)) { obj7 = val7; } } } array3.SetValue(obj7, j); } object obj12 = null; for (int k = 0; k < array3.Length; k++) { if (array3.GetValue(k) != null) { obj12 = array3.GetValue(k); break; } } if (obj12 != null) { for (int l = 0; l < array3.Length; l++) { if (array3.GetValue(l) == null) { array3.SetValue(obj12, l); } } } return array3; } } catch (Exception arg) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"MainMenuPatch hydration failed: {arg}"); } } } private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("MainMenuManager"); if (type == null) { return null; } return AccessTools.Method(type, "ActuallyStartGameActually", (Type[])null, (Type[])null); } public static void ApplyFFASelection(object mainMenuInstance, int mapinfoValue) { try { Type type = mainMenuInstance.GetType(); AccessTools.Field(type, "mapinfo")?.SetValue(mainMenuInstance, mapinfoValue); selectedFFAMapinfo = mapinfoValue; Type type2 = AccessTools.TypeByName("BootstrapManager"); object obj = AccessTools.Property(type2, "instance")?.GetValue(null, null); AccessTools.Method(type2, "ChangeLobbySize", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { 8 }); if (AccessTools.Field(type, "checkmarks")?.GetValue(mainMenuInstance) is GameObject[] array && array.Length >= 3) { array[0].SetActive(mapinfoValue == 1); array[1].SetActive(mapinfoValue == 0); array[2].SetActive(false); } try { int num = 0; Transform[] array2 = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val in array2) { if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, "EditTeamFlag", StringComparison.OrdinalIgnoreCase)) { ((Component)val).gameObject.SetActive(false); num++; } } if (num > 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"FFA: hid {num} EditTeamFlag object(s) on selection."); } } } catch { } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"FFA selected. mapinfo={mapinfoValue}. Lobby size set to 8."); } SpawnService.EnsureRuntimeContainer(); } catch (Exception arg) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"ApplyFFASelection failed: {arg}"); } } } internal static void ClearFFAState() { try { selectedFFAMapinfo = null; SpawnService.DestroyRuntimeContainer(); FFALastStand.Reset(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"FFA: cleared selection and destroyed runtime container."); } } catch { } } } [HarmonyPatch] public static class MainMenuOpenLobbyPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("MainMenuManager"); if (type == null) { return null; } return AccessTools.Method(type, "OpenLobby", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance) { //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_05f4: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Unknown result type (might be due to invalid IL or missing references) //IL_074d: Unknown result type (might be due to invalid IL or missing references) //IL_075b: Unknown result type (might be due to invalid IL or missing references) //IL_0767: Unknown result type (might be due to invalid IL or missing references) //IL_0773: Unknown result type (might be due to invalid IL or missing references) //IL_0781: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Unknown result type (might be due to invalid IL or missing references) //IL_0795: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0687: Expected O, but got Unknown //IL_081e: Unknown result type (might be due to invalid IL or missing references) //IL_0828: Expected O, but got Unknown //IL_0afa: Unknown result type (might be due to invalid IL or missing references) //IL_0b1a: Unknown result type (might be due to invalid IL or missing references) //IL_0a3f: Unknown result type (might be due to invalid IL or missing references) //IL_0a36: Unknown result type (might be due to invalid IL or missing references) //IL_0a44: Unknown result type (might be due to invalid IL or missing references) //IL_0a52: Unknown result type (might be due to invalid IL or missing references) //IL_0a5e: Unknown result type (might be due to invalid IL or missing references) //IL_0a63: Unknown result type (might be due to invalid IL or missing references) //IL_0a79: Unknown result type (might be due to invalid IL or missing references) //IL_0a85: Unknown result type (might be due to invalid IL or missing references) //IL_0a8a: Unknown result type (might be due to invalid IL or missing references) //IL_0b6e: Unknown result type (might be due to invalid IL or missing references) //IL_0b73: Unknown result type (might be due to invalid IL or missing references) //IL_0b9a: Unknown result type (might be due to invalid IL or missing references) //IL_0b9f: Unknown result type (might be due to invalid IL or missing references) //IL_0e8d: Unknown result type (might be due to invalid IL or missing references) //IL_0e7d: Unknown result type (might be due to invalid IL or missing references) try { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"OpenLobby: Postfix start"); } MainMenuPatch.ClearFFAState(); try { int num = 0; Transform[] array = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val in array) { if ((Object)(object)val == (Object)null) { continue; } switch (((Object)val).name) { case "FFA_Medium_Button": case "FFA_Large_Button": case "FreeForAllLabel_Auto": if (((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); num++; } break; } } if (num > 0) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogDebug((object)$"FFA: Pre-sanitize — hid {num} FFA UI object(s)."); } } } catch { } Type type = __instance.GetType(); if (!MainMenuPatch.IsLocalHostOrServer(__instance)) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogDebug((object)"OpenLobby: detected Client (not host) — will hide FFA UI"); } try { Transform val2 = null; try { object obj2 = AccessTools.Field(type, "Mapchoseholder")?.GetValue(__instance); GameObject val3 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val3 != null) { val2 = val3.transform; } else { Transform val4 = (Transform)((obj2 is Transform) ? obj2 : null); if (val4 != null) { val2 = val4; } } } catch { } if ((Object)(object)val2 == (Object)null) { Canvas val5 = Object.FindAnyObjectByType<Canvas>(); if ((Object)(object)val5 != (Object)null) { val2 = ((Component)val5).transform; } } int num2 = 0; Transform[] array; if ((Object)(object)val2 != (Object)null) { array = ((Component)val2).GetComponentsInChildren<Transform>(true); foreach (Transform val6 in array) { if ((Object)(object)val6 == (Object)null) { continue; } switch (((Object)val6).name) { case "FFA_Medium_Button": case "FFA_Large_Button": case "FreeForAllLabel_Auto": if (((Component)val6).gameObject.activeSelf) { ((Component)val6).gameObject.SetActive(false); num2++; } break; } } } array = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val7 in array) { if ((Object)(object)val7 == (Object)null) { continue; } switch (((Object)val7).name) { case "FFA_Medium_Button": case "FFA_Large_Button": case "FreeForAllLabel_Auto": if (((Component)val7).gameObject.activeSelf) { ((Component)val7).gameObject.SetActive(false); num2++; } break; } } if (num2 > 0) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogDebug((object)$"FFA: Client view — hid {num2} FFA selection UI objects."); } } return; } catch { return; } } ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)"OpenLobby: detected Host — will inject FFA UI if missing"); } Button[] componentsInChildren; try { FieldInfo fieldInfo = AccessTools.Field(type, "Mapchoseholder"); Transform val8 = null; object obj5 = fieldInfo?.GetValue(__instance); GameObject val9 = (GameObject)((obj5 is GameObject) ? obj5 : null); if (val9 != null) { val8 = val9.transform; } else { Transform val10 = (Transform)((obj5 is Transform) ? obj5 : null); if (val10 != null) { val8 = val10; } } if ((Object)(object)val8 != (Object)null) { if ((Object)(object)val8.Find("FFA_Medium_Button") == (Object)null && (Object)(object)val8.Find("FFA_Large_Button") == (Object)null) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogDebug((object)"OpenLobby: FFA buttons not found under Mapchoseholder — proceeding to clone"); } Button val11 = null; Button val12 = null; Transform val13 = val8; try { if ((Object)(object)val13 == (Object)null) { Canvas val14 = Object.FindAnyObjectByType<Canvas>(); val13 = (((Object)(object)val14 != (Object)null) ? ((Component)val14).transform : null); } Transform val15 = null; if ((Object)(object)val13 != (Object)null) { Transform[] array = ((Component)val13).GetComponentsInChildren<Transform>(true); foreach (Transform val16 in array) { if ((Object)(object)val16 != (Object)null && ((Object)val16).name == "Lobby") { val15 = val16; break; } } } if ((Object)(object)val15 == (Object)null) { val15 = val13; } Transform val17 = null; if ((Object)(object)val15 != (Object)null) { Transform[] array = ((Component)val15).GetComponentsInChildren<Transform>(true); foreach (Transform val18 in array) { if ((Object)(object)val18 != (Object)null && ((Object)val18).name == "mapsizecheck") { val17 = val18; break; } } } if ((Object)(object)val17 != (Object)null) { Transform val19 = null; Transform val20 = null; Transform[] array = ((Component)val17).GetComponentsInChildren<Transform>(true); foreach (Transform val21 in array) { if ((Object)(object)val21 != (Object)null && ((Object)val21).name == "SmallMap") { val19 = val21; } else if ((Object)(object)val21 != (Object)null && ((Object)val21).name == "LargeMap") { val20 = val21; } } ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogDebug((object)$"OpenLobby: sources found — SmallMap={(Object)(object)val19 != (Object)null} LargeMap={(Object)(object)val20 != (Object)null}"); } Transform val22 = null; try { GameObject val23 = GameObject.Find("ConfirmStart"); if ((Object)(object)val23 != (Object)null) { val22 = val23.transform.parent; } } catch { } if ((Object)(object)val22 == (Object)null) { val22 = (((Object)(object)val17 != (Object)null) ? val17.parent : val8); } if ((Object)(object)val19 != (Object)null) { GameObject obj7 = Object.Instantiate<GameObject>(((Component)val19).gameObject); ((Object)obj7).name = "FFA_Medium_Button"; obj7.transform.SetParent(val22, false); RectTransform component = obj7.GetComponent<RectTransform>(); RectTransform component2 = ((Component)val19).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { component.anchorMin = component2.anchorMin; component.anchorMax = component2.anchorMax; component.pivot = component2.pivot; component.sizeDelta = component2.sizeDelta; ((Transform)component).localScale = Vector3.one; ((Transform)component).localRotation = Quaternion.identity; component.anchoredPosition = component2.anchoredPosition + new Vector2(300f, 0f); } CanvasGroup component3 = obj7.GetComponent<CanvasGroup>(); if ((Object)(object)component3 != (Object)null) { component3.alpha = 1f; component3.interactable = true; component3.blocksRaycasts = true; } ContentSizeFitter componentInChildren = obj7.GetComponentInChildren<ContentSizeFitter>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } SetButtonLabel(obj7, "Medium"); val11 = obj7.GetComponent<Button>(); if ((Object)(object)val11 != (Object)null) { ((UnityEventBase)val11.onClick).RemoveAllListeners(); ((UnityEvent)val11.onClick).AddListener((UnityAction)delegate { MainMenuPatch.ApplyFFASelection(__instance, 1); }); Image component4 = ((Component)val11).GetComponent<Image>(); if ((Object)(object)component4 != (Object)null) { ((Graphic)component4).raycastTarget = true; } ((Component)val11).transform.SetSiblingIndex(0); } ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogInfo((object)$"OpenLobby: Created FFA_Medium_Button (btn={(Object)(object)val11 != (Object)null})"); } } if ((Object)(object)val20 != (Object)null) { GameObject obj8 = Object.Instantiate<GameObject>(((Component)val20).gameObject); ((Object)obj8).name = "FFA_Large_Button"; obj8.transform.SetParent(val22, false); RectTransform component5 = obj8.GetComponent<RectTransform>(); RectTransform component6 = ((Component)val20).GetComponent<RectTransform>(); if ((Object)(object)component5 != (Object)null && (Object)(object)component6 != (Object)null) { component5.anchorMin = component6.anchorMin; component5.anchorMax = component6.anchorMax; component5.pivot = component6.pivot; component5.sizeDelta = component6.sizeDelta; ((Transform)component5).localScale = Vector3.one; ((Transform)component5).localRotation = Quaternion.identity; component5.anchoredPosition = component6.anchoredPosition + new Vector2(300f, 0f); } CanvasGroup component7 = obj8.GetComponent<CanvasGroup>(); if ((Object)(object)component7 != (Object)null) { component7.alpha = 1f; component7.interactable = true; component7.blocksRaycasts = true; } ContentSizeFitter componentInChildren2 = obj8.GetComponentInChildren<ContentSizeFitter>(true); if ((Object)(object)componentInChildren2 != (Object)null) { ((Behaviour)componentInChildren2).enabled = false; } SetButtonLabel(obj8, "Large"); val12 = obj8.GetComponent<Button>(); if ((Object)(object)val12 != (Object)null) { ((UnityEventBase)val12.onClick).RemoveAllListeners(); ((UnityEvent)val12.onClick).AddListener((UnityAction)delegate { MainMenuPatch.ApplyFFASelection(__instance, 0); }); Image component8 = ((Component)val12).GetComponent<Image>(); if ((Object)(object)component8 != (Object)null) { ((Graphic)component8).raycastTarget = true; } } ManualLogSource log9 = Plugin.Log; if (log9 != null) { log9.LogInfo((object)$"OpenLobby: Created FFA_Large_Button (btn={(Object)(object)val12 != (Object)null})"); } } } } catch { } if ((Object)(object)val11 != (Object)null && (Object)(object)val12 != (Object)null) { Transform parent = ((Component)val11).transform.parent; Transform val24 = null; string[] array2 = new string[4] { "Canvas (1)/Main/JoinLobby", "Canvas/Main/JoinLobby", "Canvas (1)/Main/JoinLobbyButton", "Canvas/Main/JoinLobbyButton" }; for (int i = 0; i < array2.Length; i++) { val24 = MainMenuPatch.FindInactiveTransform(array2[i]); if ((Object)(object)val24 != (Object)null && (Object)(object)val24.parent == (Object)(object)parent) { break; } val24 = null; } int num3 = 0; if ((Object)(object)val24 != (Object)null && (Object)(object)val24.parent == (Object)(object)parent) { num3 = val24.GetSiblingIndex(); } ((Component)val11).transform.SetSiblingIndex(Mathf.Min(num3 + 1, parent.childCount - 1)); ((Component)val12).transform.SetSiblingIndex(Mathf.Min(num3 + 2, parent.childCount - 1)); LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((parent is RectTransform) ? parent : null)); HorizontalLayoutGroup component9 = ((Component)parent).GetComponent<HorizontalLayoutGroup>(); VerticalLayoutGroup component10 = ((Component)parent).GetComponent<VerticalLayoutGroup>(); GridLayoutGroup component11 = ((Component)parent).GetComponent<GridLayoutGroup>(); if ((Object)(object)component9 != (Object)null || (Object)(object)component10 != (Object)null || (Object)(object)component11 != (Object)null) { LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((parent is RectTransform) ? parent : null)); } else { RectTransform component12 = ((Component)val11).GetComponent<RectTransform>(); RectTransform component13 = ((Component)val12).GetComponent<RectTransform>(); RectTransform val25 = null; componentsInChildren = ((Component)parent).GetComponentsInChildren<Button>(true); foreach (Button val26 in componentsInChildren) { if (!((Object)(object)val26 == (Object)(object)val11) && !((Object)(object)val26 == (Object)(object)val12)) { val25 = ((Component)val26).GetComponent<RectTransform>(); if ((Object)(object)val25 != (Object)null && (Object)(object)((Component)val26).transform.parent == (Object)(object)parent) { break; } val25 = null; } } Vector2 val27 = (((Object)(object)val25 != (Object)null) ? val25.anchoredPosition : Vector2.zero); if ((Object)(object)component12 != (Object)null) { component12.anchoredPosition = val27 + new Vector2(0f, -60f); } if ((Object)(object)component13 != (Object)null) { component13.anchoredPosition = val27 + new Vector2(0f, -120f); } } RectTransform component14 = ((Component)val11).GetComponent<RectTransform>(); RectTransform component15 = ((Component)val12).GetComponent<RectTransform>(); LayoutElement val28 = ((Component)val11).GetComponent<LayoutElement>() ?? ((Component)val11).gameObject.AddComponent<LayoutElement>(); LayoutElement obj10 = ((Component)val12).GetComponent<LayoutElement>() ?? ((Component)val12).gameObject.AddComponent<LayoutElement>(); val28.ignoreLayout = true; obj10.ignoreLayout = true; if ((Object)(object)component14 != (Object)null) { component14.anchoredPosition = new Vector2(-760f, 260f); } if ((Object)(object)component15 != (Object)null) { component15.anchoredPosition = new Vector2(-560f, 260f); } ManualLogSource log10 = Plugin.Log; if (log10 != null) { log10.LogInfo((object)"FFA: positioned buttons. Medium=(-760,260) Large=(-560,260)"); } RectTransform component16 = ((Component)val11).GetComponent<RectTransform>(); RectTransform component17 = ((Component)val12).GetComponent<RectTransform>(); ManualLogSource log11 = Plugin.Log; if (log11 != null) { object obj11; Vector2 anchoredPosition; if (!((Object)(object)component16 != (Object)null)) { obj11 = "-"; } else { anchoredPosition = component16.anchoredPosition; obj11 = ((object)(Vector2)(ref anchoredPosition)).ToString(); } object obj12; if (!((Object)(object)component17 != (Object)null)) { obj12 = "-"; } else { anchoredPosition = component17.anchoredPosition; obj12 = ((object)(Vector2)(ref anchoredPosition)).ToString(); } log11.LogInfo((object)("Injected FFA Medium/Large buttons into lobby UI. medPos=" + (string?)obj11 + ", largePos=" + (string?)obj12)); } try { Transform val29 = null; Transform[] array3 = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val30 in array3) { if ((Object)(object)val30 != (Object)null && ((Object)val30).name == "FreeForAllLabel_Auto") { val29 = val30; break; } } if ((Object)(object)val29 == (Object)null) { Transform val31 = null; Transform val32 = null; Transform val33 = null; Transform val34 = parent; if ((Object)(object)val34 == (Object)null) { Canvas val35 = Object.FindAnyObjectByType<Canvas>(); val34 = (((Object)(object)val35 != (Object)null) ? ((Component)val35).transform : null); } if ((Object)(object)val34 != (Object)null) { Transform[] array = ((Component)val34).GetComponentsInChildren<Transform>(true); foreach (Transform val36 in array) { if ((Object)(object)val36 != (Object)null && ((Object)val36).name == "Lobby") { val31 = val36; break; } } } if ((Object)(object)val31 == (Object)null) { val31 = val34; } if ((Object)(object)val31 != (Object)null) { Transform[] array = ((Component)val31).GetComponentsInChildren<Transform>(true); foreach (Transform val37 in array) { if ((Object)(object)val37 != (Object)null && ((Object)val37).name == "mapsizecheck") { val32 = val37; break; } } } if ((Object)(object)val32 != (Object)null) { Transform[] array = ((Component)val32).GetComponentsInChildren<Transform>(true); foreach (Transform val38 in array) { if ((Object)(object)val38 != (Object)null && ((Object)val38).name == "nothin (2)") { val33 = val38; break; } } } if ((Object)(object)val33 != (Object)null) { GameObject val39 = Object.Instantiate<GameObject>(((Component)val33).gameObject); ((Object)val39).name = "FreeForAllLabel_Auto"; val39.transform.SetParent(((Object)(object)val32 != (Object)null) ? val32 : (((Object)(object)val34 != (Object)null) ? val34 : parent), false); bool flag = false; Text component18 = val39.GetComponent<Text>(); if ((Object)(object)component18 != (Object)null) { component18.text = "Free for all"; flag = true; } if (!flag) { Type type2 = AccessTools.TypeByName("TMPro.TextMeshProUGUI"); if (type2 != null) { Component component19 = val39.GetComponent(type2); if ((Object)(object)component19 != (Object)null) { AccessTools.Property(type2, "text")?.SetValue(component19, "Free for all", null); flag = true; } } } if (!flag) { Type type3 = AccessTools.TypeByName("TMPro.TextMeshPro"); if (type3 != null) { Component component20 = val39.GetComponent(type3); if ((Object)(object)component20 != (Object)null) { AccessTools.Property(type3, "text")?.SetValue(component20, "Free for all", null); flag = true; } } } RectTransform component21 = val39.GetComponent<RectTransform>(); Vector3 val40 = default(Vector3); ((Vector3)(ref val40))..ctor(-420f, 160f, 0f); if ((Object)(object)component21 != (Object)null) { component21.anchoredPosition3D = val40; } else { val39.transform.position = val40; } ManualLogSource log12 = Plugin.Log; if (log12 != null) { log12.LogInfo((object)$"FFA: Created FreeForAllLabel_Auto under mapsizecheck. pos=(-420,160,0) textSet={flag}"); } } else { ManualLogSource log13 = Plugin.Log; if (log13 != null) { log13.LogWarning((object)"FFA: Could not find Lobby/mapsizecheck/nothin (2) to duplicate for label."); } } } } catch (Exception arg) { ManualLogSource log14 = Plugin.Log; if (log14 != null) { log14.LogWarning((object)$"FFA: FreeForAll label creation failed: {arg}"); } } } else { ManualLogSource log15 = Plugin.Log; if (log15 != null) { log15.LogWarning((object)"OpenLobby_Postfix: failed to create FFA buttons from path and template."); } } } else { ManualLogSource log16 = Plugin.Log; if (log16 != null) { log16.LogInfo((object)"OpenLobby: FFA buttons already exist — skipping injection"); } } } else { ManualLogSource log17 = Plugin.Log; if (log17 != null) { log17.LogWarning((object)"OpenLobby: Mapchoseholder not found — cannot inject FFA buttons"); } } } catch (Exception arg2) { ManualLogSource log18 = Plugin.Log; if (log18 != null) { log18.LogWarning((object)$"OpenLobby: injection failed: {arg2}"); } } if (!FFAMode.IsActive() && !MainMenuPatch.IsFFASelected()) { return; } object? obj13 = AccessTools.Field(type, "lobbyScreen")?.GetValue(__instance); GameObject val41 = (GameObject)((obj13 is GameObject) ? obj13 : null); Transform val42 = (((Object)(object)val41 != (Object)null) ? val41.transform : null); if ((Object)(object)val42 == (Object)null) { Canvas val43 = Object.FindAnyObjectByType<Canvas>(); val42 = (((Object)(object)val43 != (Object)null) ? ((Component)val43).transform : null); } if (!((Object)(object)val42 != (Object)null)) { return; } int num4 = 0; try { object? obj14 = AccessTools.Field(type, "ctfoverlay")?.GetValue(__instance); CanvasGroup val44 = (CanvasGroup)((obj14 is CanvasGroup) ? obj14 : null); if ((Object)(object)val44 != (Object)null) { val44.alpha = 0f; val44.interactable = false; val44.blocksRaycasts = false; ((Component)val44).gameObject.SetActive(false); } try { Transform[] array = ((Component)val42).GetComponentsInChildren<Transform>(true); foreach (Transform val45 in array) { if ((Object)(object)val45 != (Object)null && string.Equals(((Object)val45).name, "EditTeamFlag", StringComparison.OrdinalIgnoreCase)) { ((Component)val45).gameObject.SetActive(false); break; } } } catch { } } catch { } componentsInChildren = ((Component)val42).GetComponentsInChildren<Button>(true); foreach (Button val46 in componentsInChildren) { ButtonClickedEvent onClick = val46.onClick; if (onClick == null) { continue; } int persistentEventCount = ((UnityEventBase)onClick).GetPersistentEventCount(); bool flag2 = false; for (int k = 0; k < persistentEventCount; k++) { switch (((UnityEventBase)onClick).GetPersistentMethodName(k)) { case "JoinTeam1": case "JoinTeam2": case "JoinLowestPlayerCountTeam": break; default: continue; } flag2 = true; break; } if (!flag2) { if ((((Object)((Component)val46).gameObject).name ?? string.Empty).Contains("JoinTeam", StringComparison.OrdinalIgnoreCase)) { flag2 = true; } else { Text componentInChildren3 = ((Component)val46).GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren3 != (Object)null && componentInChildren3.text != null && componentInChildren3.text.IndexOf("Join Team", StringComparison.OrdinalIgnoreCase) >= 0) { flag2 = true; } else { Type type4 = AccessTools.TypeByName("TMPro.TextMeshProUGUI"); if (type4 != null) { Component componentInChildren4 = ((Component)val46).GetComponentInChildren(type4, true); if ((Object)(object)componentInChildren4 != (Object)null) { string text2 = AccessTools.Property(type4, "text")?.GetValue(componentInChildren4, null) as string; if (!string.IsNullOrEmpty(text2) && text2.IndexOf("Join Team", StringComparison.OrdinalIgnoreCase) >= 0) { flag2 = true; } } } } } } if (!flag2) { bool flag3 = false; for (int l = 0; l < persistentEventCount; l++) { if (((UnityEventBase)onClick).GetPersistentMethodName(l) == "EditTeamFlag") { flag3 = true; break; } } if (!flag3) { if ((((Object)((Component)val46).gameObject).name ?? string.Empty).Equals("EditTeamFlag", StringComparison.OrdinalIgnoreCase)) { flag3 = true; } else { Text componentInChildren5 = ((Component)val46).GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren5 != (Object)null && componentInChildren5.text != null && componentInChildren5.text.IndexOf("Edit Team Flag", StringComparison.OrdinalIgnoreCase) >= 0) { flag3 = true; } else { Type type5 = AccessTools.TypeByName("TMPro.TextMeshProUGUI"); if (type5 != null) { Component componentInChildren6 = ((Component)val46).GetComponentInChildren(type5, true); if ((Object)(object)componentInChildren6 != (Object)null) { string text3 = AccessTools.Property(type5, "text")?.GetValue(componentInChildren6, null) as string; if (!string.IsNullOrEmpty(text3) && text3.IndexOf("Edit Team Flag", StringComparison.OrdinalIgnoreCase) >= 0) { flag3 = true; } } } } } } if (flag3) { ((Component)val46).gameObject.SetActive(false); num4++; continue; } } if (flag2) { ((Component)val46).gameObject.SetActive(false); num4++; } } ManualLogSource log19 = Plugin.Log; if (log19 != null) { log19.LogInfo((object)$"FFA: hid {num4} team selection buttons."); } } catch (Exception arg3) { ManualLogSource log20 = Plugin.Log; if (log20 != null) { log20.LogWarning((object)$"OpenLobby_Postfix hide team selection failed: {arg3}"); } } static void SetButtonLabel(GameObject go, string text) { Text[] componentsInChildren2 = go.GetComponentsInChildren<Text>(true); for (int m = 0; m < componentsInChildren2.Length; m++) { componentsInChildren2[m].text = text; } } } } [HarmonyPatch] public static class MainMenuStartGamePatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("MainMenuManager"); if (type == null) { return null; } return AccessTools.Method(type, "StartGame", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance) { try { if (!MainMenuPatch.ShouldHideTeamUI(__instance)) { return; } object? obj = AccessTools.Field(__instance.GetType(), "InGameLobby")?.GetValue(__instance); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val == (Object)null) { return; } int num = 0; Button[] componentsInChildren = val.GetComponentsInChildren<Button>(true); foreach (Button val2 in componentsInChildren) { ButtonClickedEvent onClick = val2.onClick; if (onClick == null) { continue; } int persistentEventCount = ((UnityEventBase)onClick).GetPersistentEventCount(); bool flag = false; for (int j = 0; j < persistentEventCount; j++) { switch (((UnityEventBase)onClick).GetPersistentMethodName(j)) { case "JoinTeam1": case "JoinTeam2": case "JoinLowestPlayerCountTeam": break; default: continue; } flag = true; break; } if (!flag) { if ((((Object)((Component)val2).gameObject).name ?? string.Empty).Contains("JoinTeam", StringComparison.OrdinalIgnoreCase)) { flag = true; } else { Text componentInChildren = ((Component)val2).GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.text != null && componentInChildren.text.IndexOf("Join Team", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; } else { Type type = AccessTools.TypeByName("TMPro.TextMeshProUGUI"); if (type != null) { Component componentInChildren2 = ((Component)val2).GetComponentInChildren(type, true); if ((Object)(object)componentInChildren2 != (Object)null) { string text = AccessTools.Property(type, "text")?.GetValue(componentInChildren2, null) as string; if (!string.IsNullOrEmpty(text) && text.IndexOf("Join Team", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; } } } } } } if (flag) { ((Component)val2).gameObject.SetActive(false); num++; } } try { int num2 = 0; Transform[] componentsInChildren2 = val.GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren2) { if ((Object)(object)val3 != (Object)null && string.Equals(((Object)val3).name, "EditTeamFlag", StringComparison.OrdinalIgnoreCase) && ((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); num2++; } } componentsInChildren2 = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val4 in componentsInChildren2) { if ((Object)(object)val4 != (Object)null && string.Equals(((Object)val4).name, "EditTeamFlag", StringComparison.OrdinalIgnoreCase) && ((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(false); num2++; } } if (num2 > 0) { num += num2; } } catch { } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"FFA: StartGame Postfix hid {num} team join controls in InGameLobby."); } } catch (Exception arg) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"StartGame Postfix failed: {arg}"); } } } } [HarmonyPatch] public static class MainMenuStartGameActualPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("MainMenuManager"); if (type == null) { return null; } return AccessTools.Method(type, "StartGameActual", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance) { //IL_08fe: Unknown result type (might be due to invalid IL or missing references) //IL_0905: Expected O, but got Unknown //IL_0760: Unknown result type (might be due to invalid IL or missing references) //IL_0765: Unknown result type (might be due to invalid IL or missing references) //IL_0778: Unknown result type (might be due to invalid IL or missing references) //IL_0783: Unknown result type (might be due to invalid IL or missing references) //IL_094d: Unknown result type (might be due to invalid IL or missing references) //IL_095c: Unknown result type (might be due to invalid IL or missing references) //IL_0797: Unknown result type (might be due to invalid IL or missing references) //IL_07a3: Unknown result type (might be due to invalid IL or missing references) //IL_07b9: Unknown result type (might be due to invalid IL or missing references) //IL_07c5: Unknown result type (might be due to invalid IL or missing references) //IL_07d1: Unknown result type (might be due to invalid IL or missing references) //IL_07dd: Unknown result type (might be due to invalid IL or missing references) //IL_0985: Unknown result type (might be due to invalid IL or missing references) //IL_0a24: Unknown result type (might be due to invalid IL or missing references) //IL_09af: Unknown result type (might be due to invalid IL or missing references) //IL_09bb: Unknown result type (might be due to invalid IL or missing references) //IL_09d1: Unknown result type (might be due to invalid IL or missing references) //IL_09dd: Unknown result type (might be due to invalid IL or missing references) //IL_09e9: Unknown result type (might be due to invalid IL or missing references) //IL_09f5: Unknown result type (might be due to invalid IL or missing references) //IL_0a4b: Unknown result type (might be due to invalid IL or missing references) //IL_0a57: Unknown result type (might be due to invalid IL or missing references) //IL_0a6d: Unknown result type (might be due to invalid IL or missing references) //IL_0a79: Unknown result type (might be due to invalid IL or missing references) //IL_0a85: Unknown result type (might be due to invalid IL or missing references) //IL_0a91: Unknown result type (might be due to invalid IL or missing references) try { if (!MainMenuPatch.ShouldHideTeamUI(__instance)) { return; } Type type = __instance.GetType(); object? obj = AccessTools.Field(type, "InGameLobby")?.GetValue(__instance); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val == (Object)null) { return; } int num = 0; Button[] componentsInChildren = val.GetComponentsInChildren<Button>(true); foreach (Button val2 in componentsInChildren) { ButtonClickedEvent onClick = val2.onClick; if (onClick == null) { continue; } int persistentEventCount = ((UnityEventBase)onClick).GetPersistentEventCount(); bool flag = false; for (int j = 0; j < persistentEventCount; j++) { switch (((UnityEventBase)onClick).GetPersistentMethodName(j)) { case "JoinTeam1": case "JoinTeam2": case "JoinLowestPlayerCountTeam": break; default: continue; } flag = true; break; } if (!flag) { if ((((Object)((Component)val2).gameObject).name ?? string.Empty).Contains("JoinTeam", StringComparison.OrdinalIgnoreCase)) { flag = true; } else { Text componentInChildren = ((Component)val2).GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.text != null && componentInChildren.text.IndexOf("Join Team", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; } else { Type type2 = AccessTools.TypeByName("TMPro.TextMeshProUGUI"); if (type2 != null) { Component componentInChildren2 = ((Component)val2).GetComponentInChildren(type2, true); if ((Object)(object)componentInChildren2 != (Object)null) { string text = AccessTools.Property(type2, "text")?.GetValue(componentInChildren2, null) as string; if (!string.IsNullOrEmpty(text) && text.IndexOf("Join Team", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; } } } } } } if (flag) { ((Component)val2).gameObject.SetActive(false); num++; } } try { int num2 = 0; Transform[] componentsInChildren2 = val.GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren2) { if ((Object)(object)val3 != (Object)null && string.Equals(((Object)val3).name, "EditTeamFlag", StringComparison.OrdinalIgnoreCase) && ((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); num2++; } } componentsInChildren2 = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val4 in componentsInChildren2) { if ((Object)(object)val4 != (Object)null && string.Equals(((Object)val4).name, "EditTeamFlag", StringComparison.OrdinalIgnoreCase) && ((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(false); num2++; } } if (num2 > 0) { num += num2; } } catch { } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"FFA: StartGameActual Postfix hid {num} team join controls in InGameLobby."); } try { Type type3 = AccessTools.TypeByName("FlagController"); Type type4 = AccessTools.TypeByName("CastleFlagCapturedNotifier"); int num3 = 0; int num4 = 0; if (type3 != null) { Object[] array = Resources.FindObjectsOfTypeAll(type3); if (array != null) { Object[] array2 = array; foreach (Object val5 in array2) { Component val6 = (Component)(object)((val5 is Component) ? val5 : null); if (val6 == null || !((Object)(object)val6 != (Object)null) || !((Object)(object)val6.gameObject != (Object)null)) { continue; } Behaviour val7 = (Behaviour)(object)((val6 is Behaviour) ? val6 : null); if (val7 != null && val7.enabled) { val7.enabled = false; } Collider component = val6.GetComponent<Collider>(); if ((Object)(object)component != (Object)null && component.enabled) { component.enabled = false; } try { Type type5 = ((object)val6).GetType(); FieldInfo fieldInfo = AccessTools.Field(type5, "flagvisual"); FieldInfo fieldInfo2 = AccessTools.Field(type5, "FlagAni"); FieldInfo fieldInfo3 = AccessTools.Field(type5, "particles"); FieldInfo fieldInfo4 = AccessTools.Field(type5, "FlagAudio"); object? obj3 = fieldInfo?.GetValue(val5); Renderer val8 = (Renderer)((obj3 is Renderer) ? obj3 : null); if (val8 != null) { val8.enabled = false; } object? obj4 = fieldInfo2?.GetValue(val5); Behaviour val9 = (Behaviour)((obj4 is Behaviour) ? obj4 : null); if (val9 != null) { val9.enabled = false; } if (fieldInfo3?.GetValue(val5) is ParticleSystem[] array3) { ParticleSystem[] array4 = array3; foreach (ParticleSystem val10 in array4) { if (!((Object)(object)val10 == (Object)null)) { val10.Stop(true, (ParticleSystemStopBehavior)0); Renderer component2 = ((Component)val10).GetComponent<Renderer>(); if (Object.op_Implicit((Object)(object)component2)) { component2.enabled = false; } } } } object? obj5 = fieldInfo4?.GetValue(val5); AudioSource val11 = (AudioSource)((obj5 is AudioSource) ? obj5 : null); if (val11 != null) { val11.Stop(); ((Behaviour)val11).enabled = false; } Renderer[] componentsInChildren3 = val6.GetComponentsInChildren<Renderer>(true); foreach (Renderer val12 in componentsInChildren3) { if ((Object)(object)val12 == (Object)null) { continue; } string text2 = ((((Object)val12).name != null) ? ((Object)val12).name.ToLowerInvariant() : string.Empty); bool flag2 = text2.Contains("flag") || text2.Contains("pole") || text2.Contains("banner"); if (!flag2) { try { Material[] sharedMaterials = val12.sharedMaterials; for (int l = 0; l < sharedMaterials.Length; l++) { if (flag2) { break; } Material val13 = sharedMaterials[l]; if (!((Object)(object)val13 == (Object)null)) { string text3 = ((((Object)val13).name != null) ? ((Object)val13).name.ToLowerInvariant() : string.Empty); if (text3.Contains("flag") || text3.Contains("pole") || text3.Contains("banner")) { flag2 = true; } } } } catch { } } if (flag2) { val12.enabled = false; } } } catch { } num3++; } } } if (type4 != null) { Object[] array5 = Resources.FindObjectsOfTypeAll(type4); if (array5 != null) { Object[] array2 = array5; foreach (Object obj8 in array2) { Component val14 = (Component)(object)((obj8 is Component) ? obj8 : null); if (val14 != null && (Object)(object)val14 != (Object)null && (Object)(object)val14.gameObject != (Object)null) { Behaviour val15 = (Behaviour)(object)((val14 is Behaviour) ? val14 : null); if (val15 != null && val15.enabled) { val15.enabled = false; } num4++; } } } } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"FFA: Deactivated {num3} FlagController and {num4} CastleFlagCapturedNotifier objects."); } } catch (Exception arg) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"FFA: Flag cleanup after StartGameActual failed: {arg}"); } } object? obj9 = AccessTools.Field(type, "ctfoverlay")?.GetValue(__instance); CanvasGroup val16 = (CanvasGroup)((obj9 is CanvasGroup) ? obj9 : null); if ((Object)(object)val16 == (Object)null) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)"FFA: ctfoverlay CanvasGroup not found; cannot apply FFA overlay."); } return; } GameObject gameObject = ((Component)val16).gameObject; if ((Object)(object)gameObject == (Object)null) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)"FFA: ctfoverlay GameObject missing; cannot apply FFA overlay."); } return; } if (!gameObject.activeSelf) { gameObject.SetActive(true); } val16.alpha = 0f; val16.interactable = false; val16.blocksRaycasts = false; RawImage componentInChildren3 = gameObject.GetComponentInChildren<RawImage>(true); Image val17 = gameObject.GetComponentInChildren<Image>(true); if ((Object)(object)componentInChildren3 == (Object)null && (Object)(object)val17 == (Object)null) { GameObject val18 = new GameObject("FFAOverlayImage", new Type[2] { typeof(RectTransform), typeof(Image) }); val18.transform.SetParent(gameObject.transform, false); val18.transform.SetAsLastSibling(); RectTransform component3 = val18.GetComponent<RectTransform>(); if ((Object)(object)component3 != (Object)null) { component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.pivot = new Vector2(0.5f, 0.5f); component3.offsetMin = Vector2.zero; component3.offsetMax = Vector2.zero; ((Transform)component3).localScale = Vector3.one; } val17 = val18.GetComponent<Image>(); if ((Object)(object)val17 != (Object)null) { ((Graphic)val17).raycastTarget = false; } ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogInfo((object)"FFA: Created FFAOverlayImage under ctfoverlay for overlay sprite."); } } Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] array6 = null; try { array6 = executingAssembly.GetManifestResourceNames(); } catch { array6 = Array.Empty<string>(); } string text4 = null; string[] array7 = array6; foreach (string text5 in array7) { if (text5.EndsWith(".Resources.ffaoverlay.png", StringComparison.OrdinalIgnoreCase) || text5.EndsWith("ffaoverlay.png", StringComparison.OrdinalIgnoreCase)) { text4 = text5; break; } } if (string.IsNullOrEmpty(text4)) { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogWarning((object)"FFA: ffaoverlay.png resource not found in assembly manifest."); } return; } byte[] array8; using (Stream stream = executingAssembly.GetManifestResourceStream(text4)) { if (stream == null) { ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogWarning((object)"FFA: Failed to open ffaoverlay.png resource stream."); } return; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); array8 = memoryStream.ToArray(); } Texture2D val19 = new Texture2D(2, 2, (TextureFormat)5, false); if (!ImageConversion.LoadImage(val19, array8)) { ManualLogSource log9 = Plugin.Log; if (log9 != null) { log9.LogWarning((object)"FFA: LoadImage failed for ffaoverlay.png."); } Object.Destroy((Object)(object)val19); return; } Sprite sprite = Sprite.Create(val19, new Rect(0f, 0f, (float)((Texture)val19).width, (float)((Texture)val19).height), new Vector2(0.5f, 0.5f), 100f); if ((Object)(object)componentInChildren3 != (Object)null) { componentInChildren3.texture = (Texture)(object)val19; ((Graphic)componentInChildren3).color = Color.white; ((Graphic)componentInChildren3).raycastTarget = false; RectTransform component4 = ((Component)componentInChildren3).GetComponent<RectTransform>(); if ((Object)(object)component4 != (Object)null) { component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.pivot = new Vector2(0.5f, 0.5f); component4.offsetMin = Vector2.zero; component4.offsetMax = Vector2.zero; ((Transform)component4).localScale = Vector3.one; } } else if ((Object)(object)val17 != (Object)null) { val17.sprite = sprite; val17.preserveAspect = true; ((Graphic)val17).color = Color.white; ((Graphic)val17).raycastTarget = false; RectTransform component5 = ((Component)val17).GetComponent<RectTransform>(); if ((Object)(object)component5 != (Object)null) { component5.anchorMin = Vector2.zero; component5.anchorMax = Vector2.one; component5.pivot = new Vector2(0.5f, 0.5f); component5.offsetMin = Vector2.zero; component5.offsetMax = Vector2.zero; ((Transform)component5).localScale = Vector3.one; } } ManualLogSource log10 = Plugin.Log; if (log10 != null) { log10.LogInfo((object)"FFA: ctfoverlay sprite swapped to ffaoverlay.png and reactivated for fade."); } } catch (Exception arg2) { ManualLogSource log11 = Plugin.Log; if (log11 != null) { log11.LogWarning((object)$"FFA: StartGameActual Postfix overlay swap failed: {arg2}"); } } } } public static class PlayerMovementPatch { } internal static class LogSampler { private static readonly Dictionary<string, int> _counts = new Dictionary<string, int>(); public static bool Every(string key, int n) { if (n <= 1) { return true; } if (!_counts.TryGetValue(key, out var value)) { value = 0; } value++; _counts[key] = value; return value % n == 0; } } [HarmonyPatch] public static class PlayerRespawnManager_AddToDeadList_Patch { [HarmonyPatch] public static class PlayerRespawnManager_IJustDied_Prefix { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("PlayerRespawnManager"); if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(AccessTools.all); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "IJustDied" && methodInfo.GetParameters().Length == 1) { return methodInfo; } } return null; } private static bool Prefix(object __instance, object pm) { try { if (!FFAMode.IsActive()) { return true; } if (FFALastStand.IsEnded()) { try { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)"FFA: Match ended at IJustDied; allowing base spectate flow."); } } catch { } } else { try { Component val = (Component)((pm is Component) ? pm : null); GameObject val2 = (((Object)(object)val != (Object)null) ? val.gameObject : null); if ((Object)(object)val2 != (Object)null && FFALastStand.IsEliminated(val2)) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogDebug((object)"FFA: Player eliminated at IJustDied; allowing base spectate flow."); } } } catch { } } } catch (Exception arg) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"FFA IJustDied prefix error: {arg}"); } } return true; } } private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("PlayerRespawnManager"); if (!(type == null)) { return AccessTools.Method(type, "AddToDeadList", (Type[])null, (Type[])null); } return null; } private static void Postfix(object __instance, GameObject DeadGuy, int pteam) { try { if (!FFAMode.IsActive() || (Object)(object)DeadGuy == (Object)null) { return; } try { string arg = ((Object)DeadGuy).name; try { Component component = DeadGuy.GetComponent("PlayerMovement"); if ((Object)(object)component != (Object)null) { string text = AccessTools.Field(((object)component).GetType(), "playername")?.GetValue(component) as string; if (!string.IsNullOrEmpty(text)) { arg = text; } } } catch { } int lives = FFALastStand.GetLives(DeadGuy); ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)$"Death[Server]: {arg} team={pteam} livesBefore={lives}"); } } catch { } FFALastStand.EnsureInitialized(DeadGuy); int num = FFALastStand.DecrementLife(DeadGuy); if (num <= 0) { FFALastStand.MarkEliminated(DeadGuy); } try { string text2 = ((Object)DeadGuy).name; try { Component component2 = DeadGuy.GetComponent("PlayerMovement"); if ((Object)(object)component2 != (Object)null) { string text3 = AccessTools.Field(((object)component2).GetType(), "playername")?.GetValue(component2) as string; if (!string.IsNullOrEmpty(text3)) { text2 = text3; } } } catch { } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogDebug((object)$"Death[Server]: {text2} team={pteam} livesAfter={num} eliminated={num <= 0}"); } } catch { } FFALastStand.MaybeEndMatch(); } catch (Exception arg2) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"FFA LPS Server Postfix error: {arg2}"); } } } } [HarmonyPatch] public static class PlayerRespawnManager_AddToDeadListObs_Patch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("PlayerRespawnManager"); if (!(type == null)) { return AccessTools.Method(type, "AddToDeadListObs", (Type[])null, (Type[])null); } return null; } private static void Postfix(object __instance, GameObject DeadGuy, int pteam) { try { if (!FFAMode.IsActive()) { return; } try { PropertyInfo propertyInfo = AccessTools.Property(__instance.GetType(), "IsServerInitialized"); if (propertyInfo != null) { object value = propertyInfo.GetValue(__instance, null); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return; } } else { FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "IsServerInitialized"); if (fieldInfo != null) { object value2 = fieldInfo.GetValue(__instance); bool flag2 = default(bool); int num2; if (value2 is bool) { flag2 = (bool)value2; num2 = 1; } else { num2 = 0; } if (((uint)num2 & (flag2 ? 1u : 0u)) != 0) { return; } } } } catch { } if ((Object)(object)DeadGuy == (Object)null) { return; } try { string arg = ((Object)DeadGuy).name; try { Component component = DeadGuy.GetComponent("PlayerMovement"); if ((Object)(object)component != (Object)null) { string text = AccessTools.Field(((object)component).GetType(), "playername")?.GetValue(component) as string; if (!string.IsNullOrEmpty(text)) { arg = text; } } } catch { } int lives = FFALastStand.GetLives(DeadGuy); ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)$"Death[Obs]: {arg} team={pteam} livesBefore={lives}"); } } catch { } FFALastStand.EnsureInitialized(DeadGuy); int num3 = FFALastStand.DecrementLife(DeadGuy); if (num3 <= 0) { FFALastStand.MarkEliminated(DeadGuy); } try { string text2 = ((Object)DeadGuy).name; try { Component component2 = DeadGuy.GetComponent("PlayerMovement"); if ((Object)(object)component2 != (Object)null) { string text3 = AccessTools.Field(((object)component2).GetType(), "playername")?.GetValue(component2) as string; if (!string.IsNullOrEmpty(text3)) { text2 = text3; } } } catch { } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogDebug((object)$"Death[Obs]: {text2} team={pteam} livesAfter={num3} eliminated={num3 <= 0}"); } } catch { } FFALastStand.MaybeEndMatch(); } catch (Exception arg2) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"FFA LPS Client Postfix error: {arg2}"); } } } } [HarmonyPatch] public static class PlayerRespawnManager_RespawnRoutine_Prefix { [CompilerGenerated] private sealed class <SkipEnumerator>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SkipEnumerator>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("PlayerRespawnManager"); if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(AccessTools.all); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "RespawnRoutine" && typeof(IEnumerator).IsAssignableFrom(methodInfo.ReturnType)) { return methodInfo; } } return null; } [IteratorStateMachine(typeof(<SkipEnumerator>d__1))] private static IEnumerator SkipEnumerator() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SkipEnumerator>d__1(0); } private static bool Prefix(object __instance, ref IEnumerator __result) { try { if (!FFAMode.IsActive()) { return true; } object? obj = AccessTools.Field(__instance.GetType(), "pmv")?.GetValue(__instance); Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { return true; } GameObject gameObject = val.gameObject; if (FFALastStand.IsEnded() || FFALastStand.IsEliminated(gameObject)) { __result = SkipEnumerator(); return false; } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"FFA RespawnRoutine prefix error: {arg}"); } } return true; } } [HarmonyPatch] public static class PlayerRespawnManager_ColiRespawnRoutine_Prefix { [CompilerGenerated] private sealed class <SkipEnumerator>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SkipEnumerator>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("PlayerRespawnManager"); if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(AccessTools.all); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "ColiRespawnRoutine" && typeof(IEnumerator).IsAssignableFrom(methodInfo.ReturnType)) { return methodInfo; } } return null; } [IteratorStateMachine(typeof(<SkipEnumerator>d__1))] private static IEnumerator SkipEnumerator() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SkipEnumerator>d__1(0); } private static bool Prefix(object __instance, ref IEnumerator __result) { try { if (!FFAMode.IsActive()) { return true; } object? obj = AccessTools.Field(__instance.GetType(), "pmv")?.GetValue(__instance); Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { return true; } GameObject gameObject = val.gameObject; if (FFALastStand.IsEnded() || FFALastStand.IsEliminated(gameObject)) { __result = SkipEnumerator(); return false; } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"FFA ColiRespawnRoutine prefix error: {arg}"); } } return true; } } [HarmonyPatch] public static class PlayerMovement_RespawnPlayer_Prefix { private static MethodBa