Decompiled source of ImpostorMod v1.0.3
plugins/ImpostorMod/ImpostorMod.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.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.Threading; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using MenuLib; using MenuLib.MonoBehaviors; using Microsoft.CodeAnalysis; using MyMod.Helpers; using Photon.Pun; using Photon.Realtime; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SplitBrudis")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5e0edfaf2774a2e591353e81058fdbfb77dacf5c")] [assembly: AssemblyProduct("ImpostorMod")] [assembly: AssemblyTitle("ImpostorMod")] [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; } } } [RequireComponent(typeof(PhotonView))] public class ActiveSettings : MonoBehaviour { private static ActiveSettings _instance; public const string HAS_IMPOSTER_MOD = "hasImpostorMod"; public const string MOD_ENABLED = "modEnabled"; public const string KILL_COOLDOWN = "killCD"; public const string KILL_RANGE = "killRange"; public const string MEETING_PER_PLAYER_COUNT = "meetingsPP"; public const string MEETING_COOLDOWN = "meetingsCD"; public const string VOTE_TIMER = "voteTimer"; public bool ModEnabledActive = true; public int KillCooldownActive = 30; public int KillRangeActive = 2; public int EmergencyMeetingsPerPlayerActive = 1; public int EmergencyMeetingCooldownActive = 20; public int VoteTimerSecondsActive = 30; public static ActiveSettings Instance { get { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { _instance = Object.FindObjectOfType<ActiveSettings>(); if ((Object)(object)_instance == (Object)null) { MyDebug.Log("Create ActiveSettings Instance."); GameObject val = new GameObject("ActiveSettings"); _instance = val.AddComponent<ActiveSettings>(); } Object.DontDestroyOnLoad((Object)(object)((Component)_instance).gameObject); } return _instance; } } private void Awake() { if ((Object)(object)_instance == (Object)null) { _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); InitBindings(); } else if ((Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } } public void InitBindings() { REPOImpostorMod.Instance.InitBindings(); ModEnabledActive = REPOImpostorMod.Instance.ModEnabled; MyDebug.Log("InitBindings ModEnabledActive=" + ModEnabledActive); KillCooldownActive = REPOImpostorMod.Instance.KillCooldown; KillRangeActive = REPOImpostorMod.Instance.KillRange; VoteTimerSecondsActive = REPOImpostorMod.Instance.VoteTimerSeconds; EmergencyMeetingsPerPlayerActive = REPOImpostorMod.Instance.EmergencyMeetingsPerPlayer; EmergencyMeetingCooldownActive = REPOImpostorMod.Instance.EmergencyMeetingCooldown; } } [RequireComponent(typeof(PhotonView))] public class AvatarRPCReceiver : MonoBehaviourPun { [PunRPC] public void RPC_Kill(int victimViewID) { MyDebug.Log($"[AvatarRPCReceiver] RPC_Kill received on {victimViewID}"); PhotonView val = PhotonView.Find(victimViewID); PlayerAvatar component = ((Component)val).GetComponent<PlayerAvatar>(); MyDebug.Log($"[AvatarRPCReceiver] playerDeathHead = {component.playerDeathHead}"); if (val.IsMine && !MyGameManager.Instance.IAmDead) { MyDebug.Log("[AvatarRPCReceiver] i got killed"); MyGameManager.Instance.MarkMeDead(); PlayerHealth playerHealth = component.playerHealth; if ((Object)(object)playerHealth != (Object)null && ((Behaviour)playerHealth).isActiveAndEnabled) { int health = playerHealth.health; playerHealth.Hurt(health, false, -1); } } } [PunRPC] public void RPC_EndGame(bool crewVictory) { MyDebug.Log($"[AvatarRPCReceiver] EndGame with crewVictory={crewVictory}"); EndGameUI.Instance.EndGame(crewVictory); } } public class EndGameUI : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass4_0 { public EndGameUI <>4__this; public Coroutine countDownCoroutine; internal void <EndGameAfterDelay>b__0() { Debug.LogError((object)"[EndGameUI] EnterArena pressed"); ((MonoBehaviour)<>4__this).StopCoroutine(countDownCoroutine); <>4__this.EnterArena(); } } [CompilerGenerated] private sealed class <ArenaCountdown>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public REPOButton button; public EndGameUI <>4__this; private int <t>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ArenaCountdown>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <t>5__1 = 50; break; case 1: <>1__state = -1; <t>5__1--; break; } if (<t>5__1 > 0) { if (SemiFunc.RunIsArena()) { MyDebug.Log("[EndGameUI] Game already moved to Arena — stopping countdown"); return false; } if ((Object)(object)button != (Object)null) { ((TMP_Text)button.labelTMP).text = $"Go to Arena ({<t>5__1} s)"; } else { Debug.LogError((object)"arena countdown button is null"); } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } MyDebug.Log("[EndGameUI] Timer run out -> EnterArena"); <>4__this.EnterArena(); 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(); } } [CompilerGenerated] private sealed class <EndGameAfterDelay>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public bool crewVictory; public EndGameUI <>4__this; private <>c__DisplayClass4_0 <>8__1; private string <title>5__2; private Color <headerColor>5__3; private string <bodyMsg>5__4; private REPOButton <button>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EndGameAfterDelay>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <title>5__2 = null; <bodyMsg>5__4 = null; <button>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00f3: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass4_0(); <>8__1.<>4__this = <>4__this; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; MyDebug.Log("[EndGameUI] EndGameAfterDelay"); UIButtonManager.Instance.HideAll(); if ((Object)(object)PlayerController.instance != (Object)null) { ((Behaviour)PlayerController.instance).enabled = false; } <title>5__2 = (crewVictory ? "Crewmates Win" : "Impostor Wins"); <headerColor>5__3 = (crewVictory ? Color.green : Color.red); <bodyMsg>5__4 = "Continue to Arena (Host can click or wait)"; <>2__current = (object)new WaitForSeconds(0.15f); <>1__state = 2; return true; case 2: <>1__state = -1; <>8__1.countDownCoroutine = null; ModUtils.OpenPagePopUp(<title>5__2, <headerColor>5__3, <bodyMsg>5__4, "Go to Arena", delegate { Debug.LogError((object)"[EndGameUI] EnterArena pressed"); ((MonoBehaviour)<>8__1.<>4__this).StopCoroutine(<>8__1.countDownCoroutine); <>8__1.<>4__this.EnterArena(); }, allowTextOverflow: true, 300f); <>2__current = (object)new WaitForSeconds(0.15f); <>1__state = 3; return true; case 3: <>1__state = -1; <button>5__5 = Object.FindObjectOfType<REPOButton>(); if ((Object)(object)<button>5__5 == (Object)null) { Debug.LogError((object)"[EndGameUI] No button found!"); return false; } ((Behaviour)<button>5__5.menuButton).enabled = PhotonNetwork.IsMasterClient; <>8__1.countDownCoroutine = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.ArenaCountdown(<button>5__5)); 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 const int ARENA_TIMER_SECONDS = 50; private static EndGameUI _instance; public static EndGameUI Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("EndGameUI"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<EndGameUI>(); } return _instance; } } [IteratorStateMachine(typeof(<EndGameAfterDelay>d__4))] private IEnumerator EndGameAfterDelay(bool crewVictory) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EndGameAfterDelay>d__4(0) { <>4__this = this, crewVictory = crewVictory }; } public void EndGame(bool crewVictory) { ((MonoBehaviour)this).StartCoroutine(EndGameAfterDelay(crewVictory)); } [IteratorStateMachine(typeof(<ArenaCountdown>d__6))] private IEnumerator ArenaCountdown(REPOButton button) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ArenaCountdown>d__6(0) { <>4__this = this, button = button }; } private void EnterArena() { KillAllPlayers(); MenuManager.instance.PageCloseAll(); } private void KillAllPlayers() { List<PlayerAvatar> list = GameDirector.instance.PlayerList.Where((PlayerAvatar av) => !av.deadSet).ToList(); MyDebug.Log("[EndGameUI] remaining player count=" + list.Count); foreach (PlayerAvatar item in list) { MyDebug.Log("[EndGameUI] remaining player=" + item.photonView.ViewID); if ((Object)(object)item != (Object)null && !item.deadSet) { MyDebug.Log("[EndGameUI] kill player=" + item.photonView.ViewID); item.photonView.RPC("RPC_Kill", (RpcTarget)0, new object[1] { item.photonView.ViewID }); } } } } public interface ICleanupable { void Cleanup(); } [RequireComponent(typeof(PhotonView))] public class ImpostorController : MonoBehaviourPunCallbacks, ICleanupable { private bool impostorPicked = false; private PlayerAvatar localAvatar; private bool isImpostor = false; private Button killButton; private float killTimer; private Text cooldownText; private bool initialized = false; public override void OnEnable() { MyDebug.Log("[ImpostorInputListener] OnEnable"); PhotonNetwork.AddCallbackTarget((object)this); SceneManager.sceneLoaded += OnSceneLoaded; } public override void OnDisable() { MyDebug.Log("[Impostor] Impostor OnDisable."); SceneManager.sceneLoaded -= OnSceneLoaded; PhotonNetwork.RemoveCallbackTarget((object)this); } private void OnSceneLoaded(Scene s, LoadSceneMode mode) { MyDebug.Log("[Impostor] OnSceneLoaded."); impostorPicked = false; isImpostor = false; if ((Object)(object)killButton != (Object)null) { Object.Destroy((Object)(object)((Component)((Component)killButton).transform.parent).gameObject); killButton = null; } } public override void OnRoomPropertiesUpdate(Hashtable props) { if (((Dictionary<object, object>)(object)props).ContainsKey((object)"impostorView")) { CacheLocalAvatar(); if (!((Object)(object)localAvatar == (Object)null)) { MyDebug.Log("[Impostor] Room property impostorView arrived → InitNonHost()"); TryAssignImpostorRole(); } } } private void TryAssignImpostorRole() { MyDebug.Log("[Impostor] localAvatar=" + (object)localAvatar); if ((Object)(object)localAvatar == (Object)null) { return; } int num = (int)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties[(object)"impostorView"]; MyGameManager.Instance._impostorViewID = num; MyDebug.Log($"[Impostor] Role assigned: isImpostor={num}"); if (!((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"impostorView", out object value) || !(value is int)) { return; } int num2 = (int)value; if (1 == 0) { return; } MyDebug.Log("[Impostor] Try to set impostor!"); bool flag = localAvatar.photonView.ViewID == num2; if (flag && !isImpostor) { isImpostor = true; MyDebug.Log("[Impostor] I am the impostor!"); CreateKillUI(); killTimer = ActiveSettings.Instance.KillCooldownActive; } else if (!flag && isImpostor) { isImpostor = false; if ((Object)(object)killButton != (Object)null) { ((Component)killButton).gameObject.SetActive(false); } } } private void Update() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_0120: Unknown result type (might be due to invalid IL or missing references) bool flag = MyGameManager.Instance.IAmDead || (SemiFunc.IsMultiplayer() && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated && (Object)(object)GameDirector.instance != (Object)null && (int)GameDirector.instance.currentState == 2 && SemiFunc.RunIsLevel()); if (MyGameManager.Instance.IAmDead || !flag) { return; } if ((Object)(object)localAvatar == (Object)null) { MyDebug.Log("[ImpostorController] initialize."); CacheLocalAvatar(); } if (!impostorPicked && PhotonNetwork.IsMasterClient) { MyDebug.Log("[ImpostorInputListener] Detected run start → Init()"); impostorPicked = true; PickImpostorAsHost(); } if (!isImpostor || !((Object)(object)killButton != (Object)null)) { return; } if (killTimer <= 0f) { PlayerAvatar val = FindTargetInCrosshair(); bool interactable = (Object)(object)val != (Object)null; ((Selectable)killButton).interactable = interactable; if (Input.GetKeyDown(REPOImpostorMod.Instance.KillKey)) { MyDebug.Log("[ImpostorInputListener] Kill hotkey pressed"); OnKillPressed(val); } } else { killTimer -= Time.deltaTime; cooldownText.text = Mathf.CeilToInt(killTimer).ToString(); if (killTimer <= 0f) { cooldownText.text = ""; } } } private void CacheLocalAvatar() { if ((Object)(object)localAvatar != (Object)null) { return; } MyDebug.Log("[ImpostorInputListener] CacheLocalAvatar()"); PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>(); foreach (PlayerAvatar val in array) { if (val.photonView.IsMine) { localAvatar = val; initialized = true; } } } private void PickImpostorAsHost() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_00dc: Expected O, but got Unknown MyDebug.Log("[ImpostorInputListener] PickImpostorAsHost()"); if ((Object)(object)localAvatar == (Object)null) { Debug.LogWarning((object)"[ImpostorInputListener] No local avatar!"); } else if (SemiFunc.IsMasterClientOrSingleplayer()) { PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>(); MyDebug.Log($"[Impostor] Found {array.Length} PlayerAvatars: " + string.Join(", ", array.Select((PlayerAvatar av) => av.photonView.ViewID))); PlayerAvatar val = array[Random.Range(0, array.Length)]; int viewID = val.photonView.ViewID; MyDebug.Log($"[Impostor] Chosen impostor ViewID = {viewID} ({SemiFunc.PlayerGetName(val)})"); Hashtable val2 = new Hashtable(); ((Dictionary<object, object>)val2).Add((object)"impostorView", (object)viewID); Hashtable val3 = val2; PhotonNetwork.CurrentRoom.SetCustomProperties(val3, (Hashtable)null, (WebFlags)null); MyDebug.Log("[Impostor]Props set"); } } private PlayerAvatar FindTargetInCrosshair() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)localAvatar == (Object)null || (Object)(object)Camera.main == (Object)null) { return null; } float num = (float)ActiveSettings.Instance.KillRangeActive * 2f; float num2 = 0f; Ray val = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)); RaycastHit val2 = default(RaycastHit); if (Physics.SphereCast(val, num2, ref val2, num)) { PlayerAvatar componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerAvatar>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)localAvatar && !componentInParent.deadSet) { return componentInParent; } } return null; } private void CreateKillUI() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) GameObject uiContainer = UIButtonManager.Instance.uiContainer; GameObject val = new GameObject("KillButton"); val.transform.SetParent(uiContainer.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(1f, 0f); val2.anchoredPosition = new Vector2(220f, -173f); val2.sizeDelta = new Vector2(60f, 60f); killButton = val.AddComponent<Button>(); UIButtonManager.Instance.killButton = killButton; UIButtonKeyLabel.AttachKeyLabel(val, killButton, REPOImpostorMod.Instance.KillKey, new Vector2(-20f, -5f)); ((Selectable)killButton).transition = (Transition)1; Texture2D val4 = new Texture2D(2, 2); ImageConversion.LoadImage(val4, ModUtils.LoadSprite("KillIcon.png")); Sprite sprite = Sprite.Create(val4, new Rect(0f, 0f, (float)((Texture)val4).width, (float)((Texture)val4).height), Vector2.one * 0.5f); Image val5 = val.AddComponent<Image>(); val5.sprite = sprite; val5.preserveAspect = true; ((Selectable)killButton).targetGraphic = (Graphic)(object)val5; ColorBlock colors = ((Selectable)killButton).colors; ((ColorBlock)(ref colors)).normalColor = Color.white; ((ColorBlock)(ref colors)).highlightedColor = Color.white; ((ColorBlock)(ref colors)).pressedColor = Color.gray; ((ColorBlock)(ref colors)).disabledColor = new Color(0.3f, 0.3f, 0.3f, 1f); ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((Selectable)killButton).colors = colors; ((Selectable)killButton).interactable = false; GameObject val6 = new GameObject("CooldownText"); val6.transform.SetParent(val.transform, false); cooldownText = val6.AddComponent<Text>(); cooldownText.alignment = (TextAnchor)4; cooldownText.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); cooldownText.fontSize = 40; ((Graphic)cooldownText).color = Color.white; ((Graphic)cooldownText).raycastTarget = false; RectTransform rectTransform = ((Graphic)cooldownText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; val3 = (rectTransform.offsetMin = (rectTransform.offsetMax = Vector2.zero)); rectTransform.anchoredPosition = new Vector2(10f, 0f); Outline val8 = val6.AddComponent<Outline>(); ((Shadow)val8).effectColor = Color.black; ((Shadow)val8).effectDistance = new Vector2(2f, -2f); } private byte[] LoadSprite(string name) { string location = Assembly.GetExecutingAssembly().Location; string directoryName = Path.GetDirectoryName(location); string path = Path.Combine(directoryName, "Assets", name); return File.ReadAllBytes(path); } private void OnKillPressed(PlayerAvatar victim) { MyDebug.Log("[ImpostorInputListener] Kill Pressed"); if (!((Object)(object)victim == (Object)null)) { int viewID = victim.photonView.ViewID; MyDebug.Log($"[ImpostorInputListener] Broadcasting RPC_Kill to all for ViewID={viewID}"); killTimer = ActiveSettings.Instance.KillCooldownActive; ((Selectable)killButton).interactable = false; victim.photonView.RPC("RPC_Kill", (RpcTarget)0, new object[1] { viewID }); } } public void Cleanup() { MyDebug.Log("[ImpostorController] clean up"); if ((Object)(object)killButton != (Object)null) { Object.Destroy((Object)(object)((Component)((Component)killButton).gameObject.transform.parent).gameObject); killButton = null; } impostorPicked = false; initialized = false; isImpostor = false; } } [RequireComponent(typeof(PhotonView))] public class LobbyPopupController : MonoBehaviourPunCallbacks { [CompilerGenerated] private sealed class <EnableModAfterDelay>d__19 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ModManager modManager; public LobbyPopupController <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnableModAfterDelay>d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; modManager?.EnableMod(); 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(); } } public REPOPopupPage impostorSettingsPage; private REPOToggle ModEnabledToggle; private REPOSlider KillCooldownSlider; private REPOSlider KillRangeSlider; private REPOSlider MeetingsCountSlider; private REPOSlider MeetingsCooldownSlider; private REPOSlider VoteDurationSlider; private static LobbyPopupController _instance; private bool joinedRoom = false; private GameObject donationGO; private REPOButton donateButton; private REPOButton payPalButton; private REPOButton kofiButton; private REPOButton closeDonationPopupButton; public static LobbyPopupController Instance { get { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { MyDebug.Log("Create LobbyPopupController Instance"); GameObject val = new GameObject("LobbyPopupUpdater"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<LobbyPopupController>(); } return _instance; } } public void Cleanup() { MyDebug.Log("[LobbyPopupController] Cleanup"); if ((Object)(object)impostorSettingsPage != (Object)null && (Object)(object)impostorSettingsPage.menuPage != (Object)null) { impostorSettingsPage.ClosePage(true); impostorSettingsPage = null; } if ((Object)(object)donationGO != (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); } joinedRoom = false; } private void Update() { if (!joinedRoom || PhotonNetwork.CurrentRoom == null || !SemiFunc.RunIsLobbyMenu() || !((Object)(object)MenuHolder.instance != (Object)null)) { return; } int num = 0; if ((Object)(object)MenuManager.instance != (Object)null && MenuManager.instance.addedPagesOnTop != null) { num = MenuManager.instance.addedPagesOnTop.Count((MenuPage page) => (Object)(object)page != (Object)null); int num2 = MenuManager.instance.addedPagesOnTop.RemoveAll((MenuPage page) => (Object)(object)page == (Object)null); } if (num == 0 && ((Object)(object)impostorSettingsPage == (Object)null || (Object)(object)impostorSettingsPage.menuPage == (Object)null)) { MyDebug.Log("[LobbyPopupController] Open MenuPageLobby again"); impostorSettingsPage = CreateImpostorSettingsUI(); } } public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { MyDebug.Log("OnPlayerPropertiesUpdate"); if (!((Dictionary<object, object>)(object)changedProps).ContainsKey((object)"hasImpostorMod")) { return; } List<GameObject> playerEntries = GetPlayerEntries(); foreach (GameObject item in playerEntries) { AttachModIcon(item); } } public static MenuPage GetActiveLobbyPage() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if ((Object)(object)MenuManager.instance == (Object)null) { return null; } MenuPage currentMenuPage = MenuManager.instance.currentMenuPage; if ((Object)(object)currentMenuPage != (Object)null && (int)currentMenuPage.menuPageIndex == 8) { return currentMenuPage; } Debug.LogWarning((object)"[LobbyUIHelper] No active Lobby page right now."); return null; } public static Transform GetPlayerListRoot() { MenuPage activeLobbyPage = GetActiveLobbyPage(); if ((Object)(object)activeLobbyPage == (Object)null) { return null; } Transform val = ((Component)activeLobbyPage).transform.Find("Player List"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)"[LobbyUIHelper] Could not find 'Player List' transform"); } return val; } public static List<GameObject> GetPlayerEntries() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown List<GameObject> list = new List<GameObject>(); Transform playerListRoot = GetPlayerListRoot(); if ((Object)(object)playerListRoot == (Object)null) { return list; } foreach (Transform item in playerListRoot) { Transform val = item; list.Add(((Component)val).gameObject); MyDebug.Log("[LobbyUIHelper] Found player entry: " + ((Object)val).name); } return list; } public static void AttachModIcon(GameObject entry) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)entry == (Object)null)) { Transform val = entry.transform.Find("ModIcon"); if (!((Object)(object)val != (Object)null)) { GameObject val2 = new GameObject("ModIcon", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(entry.transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(18f, 18f); component.anchoredPosition = new Vector2(128f, -74f); Image component2 = val2.GetComponent<Image>(); component2.sprite = ModUtils.LoadSpriteFromFile("Logo.png"); MyDebug.Log("[LobbyUIHelper] Attached mod icon to " + ((Object)entry).name); } } } [IteratorStateMachine(typeof(<EnableModAfterDelay>d__19))] private IEnumerator EnableModAfterDelay(ModManager modManager) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnableModAfterDelay>d__19(0) { <>4__this = this, modManager = modManager }; } public void JoinRoom() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00d8: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_016d: Expected O, but got Unknown ModManager[] array = Object.FindObjectsOfType<ModManager>(); ModManager modManager = Object.FindObjectOfType<ModManager>(); MyDebug.Log("[LobbyPopupController]modManager.length=" + array.Length); MyDebug.Log("[LobbyPopupController]modManager=" + (object)modManager); MyDebug.Log("[LobbyPopupController]modManager.mainGameInitialized=" + modManager.mainGameInitialized); if ((Object)(object)modManager != (Object)null && modManager.mainGameInitialized) { MyDebug.Log("[LobbyPopupController] Call controller Cleanup()..."); modManager.CleanUp(); } joinedRoom = true; if (PhotonNetwork.IsMasterClient) { MyDebug.Log("[LobbyPopupController] OnJoinedRoom Host joined."); LoadMySettings(); PushSettingsToRoom(); CreateImpostorSettingsUI(); Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"hasImpostorMod", (object)true); Hashtable val2 = val; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); return; } MyDebug.Log("[LobbyPopupController] OnJoinedRoom Player joined."); if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).ContainsKey((object)"hasImpostorMod") && (bool)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties[(object)"hasImpostorMod"]) { MyDebug.Log("[LobbyPopupController] host Has Mod."); CreateImpostorSettingsUI(); ApplySettingsFromRoom(((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties); Hashtable val3 = new Hashtable(); ((Dictionary<object, object>)val3).Add((object)"hasImpostorMod", (object)true); Hashtable val4 = val3; PhotonNetwork.LocalPlayer.SetCustomProperties(val4, (Hashtable)null, (WebFlags)null); return; } MyDebug.Log("[LobbyPopupController] Host does not have the Impostor Mod"); REPOPopupPage val5 = MenuAPI.CreateREPOPopupPage("Host does not have the Impostor Mod :(", (PresetSide)1, false, false, 1.2f); val5.OpenPage(true); val5.closeMenuOnEscape = false; impostorSettingsPage = val5; if (modManager.ModEnabled) { modManager.DisableMod(); } } private void PushSettingsToRoom() { //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) //IL_0017: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00bb: Expected O, but got Unknown Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"hasImpostorMod", (object)true); ((Dictionary<object, object>)val).Add((object)"modEnabled", (object)ActiveSettings.Instance.ModEnabledActive); ((Dictionary<object, object>)val).Add((object)"killCD", (object)ActiveSettings.Instance.KillCooldownActive); ((Dictionary<object, object>)val).Add((object)"killRange", (object)ActiveSettings.Instance.KillRangeActive); ((Dictionary<object, object>)val).Add((object)"meetingsPP", (object)ActiveSettings.Instance.EmergencyMeetingsPerPlayerActive); ((Dictionary<object, object>)val).Add((object)"meetingsCD", (object)ActiveSettings.Instance.EmergencyMeetingCooldownActive); ((Dictionary<object, object>)val).Add((object)"voteTimer", (object)ActiveSettings.Instance.VoteTimerSecondsActive); Hashtable val2 = val; PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } private static void SetRoomProp(string key, int value) { //IL_000c: 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_0022: Expected O, but got Unknown MyDebug.Log("[LobbyPopupController] SetRoomProp"); Hashtable val = new Hashtable { [(object)key] = value }; ApplySettingsFromRoom(val); PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } private static void SetRoomProp(string key, bool value) { //IL_000c: 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_0022: Expected O, but got Unknown MyDebug.Log("[LobbyPopupController] SetRoomProp"); Hashtable val = new Hashtable { [(object)key] = value }; ApplySettingsFromRoom(val); PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } public void LoadMySettings() { MyDebug.Log("[LobbyPopupController] LoadMySettings"); ActiveSettings.Instance.InitBindings(); } public REPOPopupPage CreateImpostorSettingsUI() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown MyDebug.Log("[LobbyPopupController] CreateImpostorSettingsUI"); REPOPopupPage val2 = MenuAPI.CreateREPOPopupPage("Impostor Mod Settings", false, false, 1.2f, (Vector2?)new Vector2(55f, 0f)); val2.OpenPage(true); val2.closeMenuOnEscape = false; impostorSettingsPage = val2; val2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) ModEnabledToggle = MenuAPI.CreateREPOToggle("Mod Enabled", (Action<bool>)delegate(bool val) { if (PhotonNetwork.IsMasterClient) { SetRoomProp("modEnabled", val); } }, scrollView, Vector2.zero, "On", "Off", ActiveSettings.Instance.ModEnabledActive); if (!PhotonNetwork.IsMasterClient) { Button[] componentsInChildren = ((Component)ModEnabledToggle).GetComponentsInChildren<Button>(); Button[] array = componentsInChildren; foreach (Button val3 in array) { ((Selectable)val3).interactable = false; ((Behaviour)val3).enabled = false; ((UnityEventBase)val3.onClick).RemoveAllListeners(); } Slider componentInChildren = ((Component)ModEnabledToggle).GetComponentInChildren<Slider>(); if ((Object)(object)componentInChildren != (Object)null) { ((Selectable)componentInChildren).interactable = false; } } return ((Component)ModEnabledToggle).GetComponent<RectTransform>(); }, 0f, 0f); KillCooldownSlider = CreateSlider(val2, "Kill Cooldown", "", "killCD", 1f, 600f, ActiveSettings.Instance.KillCooldownActive, " s"); KillRangeSlider = CreateSlider(val2, "Kill Distance", "", "killRange", 1f, 20f, ActiveSettings.Instance.KillRangeActive, " m"); MeetingsCountSlider = CreateSlider(val2, "Emergency Meetings Per Player", "", "meetingsPP", 0f, 10f, ActiveSettings.Instance.EmergencyMeetingsPerPlayerActive, ""); MeetingsCooldownSlider = CreateSlider(val2, "Emergency Cooldown", "", "meetingsCD", 1f, 600f, ActiveSettings.Instance.EmergencyMeetingCooldownActive, " s"); VoteDurationSlider = CreateSlider(val2, "Voting Time", "", "voteTimer", 10f, 300f, ActiveSettings.Instance.VoteTimerSecondsActive, " s"); CreateDonationIcon(val2); return val2; } private void LateUpdate() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)donateButton != (Object)null) { ((Graphic)((Selectable)donateButton.menuButton.button).image).color = new Color(1f, 1f, 1f, 1f); } if ((Object)(object)payPalButton != (Object)null) { ((Graphic)((Selectable)payPalButton.menuButton.button).image).color = new Color(1f, 1f, 1f, 1f); } if ((Object)(object)kofiButton != (Object)null) { ((Graphic)((Selectable)kofiButton.menuButton.button).image).color = new Color(1f, 1f, 1f, 1f); } } private void ShowDonatePopup() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown REPOPopupPage popup = MenuAPI.CreateREPOPopupPage("THANK YOU!", false, false, 0f, (Vector2?)new Vector2(410f, 80f)); RectTransform[] componentsInChildren = ((Component)popup).GetComponentsInChildren<RectTransform>(); RectTransform[] array = componentsInChildren; foreach (RectTransform val in array) { val.sizeDelta = new Vector2(10f, 10f); } popup.rectTransform.sizeDelta = new Vector2(100f, 80f); popup.maskRectTransform.sizeDelta = new Vector2(100f, 80f); RectTransform rectTransform = ((TMP_Text)popup.headerTMP).rectTransform; rectTransform.anchoredPosition -= new Vector2(2f, 105f); ((TMP_Text)popup.headerTMP).enableAutoSizing = false; ((TMP_Text)popup.headerTMP).overflowMode = (TextOverflowModes)0; ((TMP_Text)popup.headerTMP).fontSize = 15f; ((TMP_Text)popup.headerTMP).rectTransform.sizeDelta = new Vector2(80f, 20f); popup.OpenPage(true); popup.closeMenuOnEscape = true; popup.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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) payPalButton = MenuAPI.CreateREPOButton(" ", (Action)delegate { MyDebug.Log("[Donation] PayPal clicked"); Application.OpenURL("https://www.paypal.com/ncp/payment/YAJRFTRSDLXF2"); }, parent, default(Vector2)); payPalButton.overrideButtonSize = new Vector2(90f, 40f); ((Component)payPalButton).GetComponent<RectTransform>().anchoredPosition = Vector2.zero; Image component3 = ((Component)payPalButton).GetComponent<Image>(); if ((Object)(object)component3 != (Object)null) { Texture2D val3 = new Texture2D(1, 1); ImageConversion.LoadImage(val3, ModUtils.LoadSprite("paypal-icon.png")); Sprite sprite2 = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), Vector2.one * 0.5f); component3.sprite = sprite2; component3.preserveAspect = true; ((Graphic)component3).raycastTarget = true; } RectTransform component4 = ((Component)payPalButton.menuButton).GetComponent<RectTransform>(); component4.sizeDelta = new Vector2(50f, 50f); ((Transform)component4).position = Vector2.op_Implicit(new Vector2(485f, 55f)); ((Transform)component4).SetAsLastSibling(); }); popup.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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) kofiButton = MenuAPI.CreateREPOButton(" ", (Action)delegate { MyDebug.Log("[Donation] Ko-Fi clicked"); Application.OpenURL("https://ko-fi.com/Z8Z31KKWWM"); }, parent, default(Vector2)); kofiButton.overrideButtonSize = new Vector2(100f, 30f); ((Component)kofiButton).GetComponent<RectTransform>().anchoredPosition = Vector2.zero; Image component = ((Component)kofiButton).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { Texture2D val2 = new Texture2D(1, 1); ImageConversion.LoadImage(val2, ModUtils.LoadSprite("kofi-icon.png")); Sprite sprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), Vector2.one * 0.5f); component.sprite = sprite; component.preserveAspect = true; ((Graphic)component).raycastTarget = true; } RectTransform component2 = ((Component)kofiButton.menuButton).GetComponent<RectTransform>(); component2.sizeDelta = new Vector2(50f, 50f); ((Transform)component2).position = Vector2.op_Implicit(new Vector2(480f, 35f)); ((Transform)component2).SetAsLastSibling(); }); popup.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) closeDonationPopupButton = MenuAPI.CreateREPOButton("x", (Action)delegate { popup.ClosePage(true); }, parent, new Vector2(568f, 100f)); ((TMP_Text)closeDonationPopupButton.labelTMP).fontSize = 12f; ((Selectable)closeDonationPopupButton.menuButton.button).transition = (Transition)0; }); } private void CreateDonationIcon(REPOPopupPage page) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0016: 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) //IL_0038: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) donateButton = MenuAPI.CreateREPOButton(" ", (Action)delegate { ShowDonatePopup(); MyDebug.Log("[Donation] Opening donation popup..."); }, parent, default(Vector2)); donateButton.overrideButtonSize = new Vector2(50f, 50f); Image component = ((Component)donateButton).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { Texture2D val = new Texture2D(1, 1); ImageConversion.LoadImage(val, ModUtils.LoadSprite("DonateIcon.png")); Sprite sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), Vector2.one * 0.5f); component.sprite = sprite; component.preserveAspect = true; ((Graphic)component).raycastTarget = true; } RectTransform component2 = ((Component)donateButton.menuButton).GetComponent<RectTransform>(); component2.sizeDelta = new Vector2(50f, 50f); ((Transform)component2).position = Vector2.op_Implicit(new Vector2(400f, 35f)); ((Transform)component2).SetAsLastSibling(); GameObject tooltip = TooltipHelpers.CreateTooltip(parent, "Click to support this mod!"); TooltipTrigger tooltipTrigger = ((Component)donateButton).gameObject.GetComponent<TooltipTrigger>(); if ((Object)(object)tooltipTrigger == (Object)null) { tooltipTrigger = ((Component)donateButton).gameObject.AddComponent<TooltipTrigger>(); } tooltipTrigger.tooltip = tooltip; tooltipTrigger.offset = new Vector2(10f, 20f); tooltipTrigger.showDelay = 0.12f; MenuButtonHoverWatcher menuButtonHoverWatcher = ((Component)donateButton).gameObject.GetComponent<MenuButtonHoverWatcher>(); if ((Object)(object)menuButtonHoverWatcher == (Object)null) { menuButtonHoverWatcher = ((Component)donateButton).gameObject.AddComponent<MenuButtonHoverWatcher>(); } menuButtonHoverWatcher.tooltip = tooltip; menuButtonHoverWatcher.showDelay = 0.12f; }); } private void DisableSlider(REPOSlider slider) { Button[] componentsInChildren = ((Component)slider).GetComponentsInChildren<Button>(true); Button[] array = componentsInChildren; foreach (Button val in array) { ((Selectable)val).interactable = false; ((UnityEventBase)val.onClick).RemoveAllListeners(); } Graphic[] componentsInChildren2 = ((Component)slider).GetComponentsInChildren<Graphic>(true); Graphic[] array2 = componentsInChildren2; foreach (Graphic val2 in array2) { val2.raycastTarget = false; } Graphic component = ((Component)slider).GetComponent<Graphic>(); if ((Object)(object)component != (Object)null) { component.raycastTarget = false; } ((Behaviour)slider).enabled = false; CanvasGroup val3 = ((Component)slider).GetComponent<CanvasGroup>(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)slider).gameObject.AddComponent<CanvasGroup>(); } val3.blocksRaycasts = false; typeof(REPOSlider).GetField("onValueChanged", BindingFlags.Instance | BindingFlags.Public)?.SetValue(slider, null); } private REPOSlider CreateSlider(REPOPopupPage page, string label, string description, string propKey, float min, float max, float defaultValue, string postfix) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown REPOSlider slider = null; page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) string text = label; string text2 = description; Action<float> obj = delegate(float val) { if (PhotonNetwork.IsMasterClient) { SetRoomProp(propKey, (int)val); } }; float num = min; float num2 = max; float num3 = defaultValue; string text3 = postfix; slider = MenuAPI.CreateREPOSlider(text, text2, obj, scrollView, default(Vector2), num, num2, 0, num3, "", text3, (BarBehavior)0); if (!PhotonNetwork.IsMasterClient) { DisableSlider(slider); } return ((Component)slider).GetComponent<RectTransform>(); }, 0f, 0f); return slider; } private void RefreshSlidersFromActiveSettings(REPOSlider slider, int value) { if ((Object)(object)slider == (Object)null) { Debug.LogWarning((object)$"[LobbyPopupController] RefreshSlidersFromActiveSettings: slider is null for value={value}"); return; } MyDebug.Log("slider=" + (object)slider); slider.SetValue((float)value, false); } private void RefreshToggleFromActiveSettings(bool value) { if ((Object)(object)ModEnabledToggle == (Object)null) { Debug.LogWarning((object)$"[LobbyPopupController] RefreshToggleFromActiveSettings: ModEnabledToggle is null for value={value}"); return; } MyDebug.Log("ModEnabledToggle=" + (object)ModEnabledToggle); ModEnabledToggle.SetState(value, false); } private static void ApplySettingsFromRoom(Hashtable props) { MyDebug.Log("[LobbyPopupController] ApplySettingsFromRoom"); if (((Dictionary<object, object>)(object)props).TryGetValue((object)"modEnabled", out object value)) { ActiveSettings.Instance.ModEnabledActive = (bool)value; } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"killCD", out object value2)) { ActiveSettings.Instance.KillCooldownActive = (int)value2; } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"killRange", out object value3)) { ActiveSettings.Instance.KillRangeActive = (int)value3; } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"meetingsPP", out object value4)) { ActiveSettings.Instance.EmergencyMeetingsPerPlayerActive = (int)value4; } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"meetingsCD", out object value5)) { ActiveSettings.Instance.EmergencyMeetingCooldownActive = (int)value5; } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"voteTimer", out object value6)) { ActiveSettings.Instance.VoteTimerSecondsActive = (int)value6; } } public override void OnRoomPropertiesUpdate(Hashtable props) { MyDebug.Log("[LobbyPopupController] OnRoomPropertiesUpdate"); if (!PhotonNetwork.IsMasterClient) { UpdateRoomProperties(props); } } public void UpdateRoomProperties(Hashtable props) { MyDebug.Log("[LobbyPopupController] UpdateRoomProperties" + (object)props); LobbyPopupController[] components = ((Component)this).GetComponents<LobbyPopupController>(); MyDebug.Log($"[Diag] Found {components.Length} LobbyPopupController components on {((Object)((Component)this).gameObject).name}"); if (((Dictionary<object, object>)(object)props).TryGetValue((object)"modEnabled", out object value)) { MyDebug.Log("[LobbyPopupController] props value=" + value); ActiveSettings.Instance.ModEnabledActive = (bool)value; RefreshToggleFromActiveSettings((bool)value); } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"killCD", out object value2)) { MyDebug.Log("[LobbyPopupController] props value=" + value2); ActiveSettings.Instance.KillCooldownActive = (int)value2; RefreshSlidersFromActiveSettings(KillCooldownSlider, (int)value2); } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"killRange", out object value3)) { MyDebug.Log("[LobbyPopupController] props value=" + value3); ActiveSettings.Instance.KillRangeActive = (int)value3; RefreshSlidersFromActiveSettings(KillRangeSlider, (int)value3); } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"meetingsPP", out object value4)) { MyDebug.Log("[LobbyPopupController] props value=" + value4); ActiveSettings.Instance.EmergencyMeetingsPerPlayerActive = (int)value4; RefreshSlidersFromActiveSettings(MeetingsCountSlider, (int)value4); } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"meetingsCD", out object value5)) { MyDebug.Log("[LobbyPopupController] props value=" + value5); ActiveSettings.Instance.EmergencyMeetingCooldownActive = (int)value5; RefreshSlidersFromActiveSettings(MeetingsCooldownSlider, (int)value5); } if (((Dictionary<object, object>)(object)props).TryGetValue((object)"voteTimer", out object value6)) { MyDebug.Log("[LobbyPopupController] props value=" + value6); ActiveSettings.Instance.VoteTimerSecondsActive = (int)value6; RefreshSlidersFromActiveSettings(VoteDurationSlider, (int)value6); } } } [RequireComponent(typeof(PhotonView))] public class MeetingController : MonoBehaviourPunCallbacks, ICleanupable { private int meetingsLeft; private float meetingCooldown; private bool initialized = false; private Button meetingButton; private PlayerAvatar localAvatar; private VoteController _voteController; private Text cooldownText; private REPOPopupPage meetingPage; private bool a = true; private void Awake() { _voteController = ((Component)this).GetComponent<VoteController>(); if ((Object)(object)_voteController == (Object)null) { Debug.LogError((object)"[ReportController] Couldn’t find VoteController!"); } } private void Update() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_019a: Unknown result type (might be due to invalid IL or missing references) bool flag = MyGameManager.Instance.IAmDead || (SemiFunc.IsMultiplayer() && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated && (Object)(object)GameDirector.instance != (Object)null && SemiFunc.RunIsLevel() && (int)GameDirector.instance.currentState == 2); if (MyGameManager.Instance.IAmDead || !flag) { return; } if (!initialized) { CacheLocalAvatar(); SaveHostSettingsToConfig(); LobbyPopupController.Instance.Cleanup(); ModManager modManager = Object.FindObjectOfType<ModManager>(); if (!ActiveSettings.Instance.ModEnabledActive) { if (modManager.ModEnabled) { modManager.DisableMod(); } return; } CreateMeetingButton(); meetingsLeft = ActiveSettings.Instance.EmergencyMeetingsPerPlayerActive; meetingCooldown = ActiveSettings.Instance.EmergencyMeetingCooldownActive; initialized = true; modManager.mainGameInitialized = true; MyDebug.Log("[MeetingController] initialize."); } bool flag2 = (Object)(object)localAvatar.RoomVolumeCheck != (Object)null && localAvatar.RoomVolumeCheck.inTruck; if (flag2) { ShowMeetingButton(); } else { HideMeetingButton(); } if (flag2 && meetingCooldown <= 0f) { ((Selectable)meetingButton).interactable = true; if ((Object)(object)MenuManager.instance?.currentMenuPage == (Object)null && Input.GetKeyDown(REPOImpostorMod.Instance.MeetingKey)) { MyDebug.Log("[MeetingController] Meeting hotkey pressed"); OnMeetingPressed(); } } if (meetingCooldown > 0f) { meetingCooldown -= Time.deltaTime; cooldownText.text = Mathf.CeilToInt(meetingCooldown).ToString(); if (meetingCooldown <= 0f) { meetingCooldown = 0f; cooldownText.text = ""; } } } private void SaveHostSettingsToConfig() { ActiveSettings instance = ActiveSettings.Instance; REPOImpostorMod.Instance.SaveConfig(instance); } private void ShowMeetingButton() { ((Component)meetingButton).gameObject.SetActive(true); } private void HideMeetingButton() { ((Component)meetingButton).gameObject.SetActive(false); } private void CreateMeetingButton() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_00f3: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) MyDebug.Log("CreateMeetingButton"); GameObject uiContainer = UIButtonManager.Instance.uiContainer; GameObject val = new GameObject("MeetingButton"); val.transform.SetParent(uiContainer.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(1f, 0f); val2.anchoredPosition = new Vector2(120f, -170f); val2.sizeDelta = new Vector2(60f, 60f); meetingButton = val.AddComponent<Button>(); UIButtonManager.Instance.meetingButton = meetingButton; UIButtonKeyLabel.AttachKeyLabel(val, meetingButton, REPOImpostorMod.Instance.MeetingKey, new Vector2(-31f, -6f)); Image val4 = val.AddComponent<Image>(); Texture2D val5 = new Texture2D(2, 2); ImageConversion.LoadImage(val5, ModUtils.LoadSprite("EmergencyMeetingIcon.png")); val4.sprite = Sprite.Create(val5, new Rect(0f, 0f, (float)((Texture)val5).width, (float)((Texture)val5).height), Vector2.one * 0.5f); val4.preserveAspect = true; ((Selectable)meetingButton).targetGraphic = (Graphic)(object)val4; GameObject val6 = new GameObject("CooldownText"); val6.transform.SetParent(val.transform, false); cooldownText = val6.AddComponent<Text>(); cooldownText.alignment = (TextAnchor)4; cooldownText.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); cooldownText.fontSize = 40; ((Graphic)cooldownText).color = Color.white; ((Graphic)cooldownText).raycastTarget = false; ((Selectable)meetingButton).interactable = false; } private void OnMeetingPressed() { ((Selectable)meetingButton).interactable = false; PopupManager.Instance.OpenManagedPopupDelayed(() => MenuAPI.CreateREPOPopupPage("Emergency Meeting", false, true, 1.5f, (Vector2?)new Vector2(-110f, 0f)), delegate(REPOPopupPage meetingPage) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown UIButtonManager.Instance.HideAll(); meetingPage.rectTransform.sizeDelta = new Vector2(140f, 10f); meetingPage.maskRectTransform.sizeDelta = new Vector2(140f, 10f); RectTransform rectTransform = ((TMP_Text)meetingPage.headerTMP).rectTransform; rectTransform.anchoredPosition += new Vector2(0f, -50f); ((Graphic)meetingPage.headerTMP).color = Color.red; ((TMP_Text)meetingPage.headerTMP).enableAutoSizing = false; ((TMP_Text)meetingPage.headerTMP).overflowMode = (TextOverflowModes)0; ((TMP_Text)meetingPage.headerTMP).fontSize = 45f; ((TMP_Text)meetingPage.headerTMP).rectTransform.sizeDelta = new Vector2(300f, 75f); meetingPage.OpenPage(true); meetingPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) string text = "YOU HAVE\n" + $"{meetingsLeft}\n" + "EMERGENCY MEETING" + ((meetingsLeft == 1) ? "" : "S") + " LEFT"; REPOLabel val = MenuAPI.CreateREPOLabel(text, parent, new Vector2(240f, 180f)); TextMeshProUGUI labelTMP = val.labelTMP; ((TMP_Text)labelTMP).alignment = (TextAlignmentOptions)514; ((TMP_Text)labelTMP).fontSize = 29f; ((TMP_Text)labelTMP).enableAutoSizing = false; ((TMP_Text)labelTMP).fontSizeMin = 29f; ((TMP_Text)labelTMP).fontSizeMax = 29f; ((Graphic)labelTMP).color = Color.white; ((TMP_Text)labelTMP).fontStyle = (FontStyles)0; RectTransform component = ((Component)val).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0.37f, 0.5f); component.anchoredPosition = new Vector2(0f, -35f); component.sizeDelta = new Vector2(0f, 100f); if (meetingsLeft > 0) { REPOButton val2 = MenuAPI.CreateREPOButton("USE IT", (Action)delegate { meetingPage.ClosePage(true); meetingsLeft--; StartMeeting(); }, parent, new Vector2(260f, 75f)); ((Selectable)val2.menuButton.button).transition = (Transition)0; } REPOButton val3 = MenuAPI.CreateREPOButton("RETURN", (Action)delegate { meetingPage.ClosePage(true); ((Selectable)meetingButton).interactable = true; MyDebug.Log("[MeetingController] ShowAll triggered from MeetingController::RETURN"); UIButtonManager.Instance.ShowAll(); }, parent, new Vector2(400f, 75f)); ((Selectable)val3.menuButton.button).transition = (Transition)0; }); }); } private void StartMeeting() { ((Selectable)meetingButton).interactable = false; int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber; MyDebug.Log("[MeetingController] StartMeeting clicked"); ((MonoBehaviourPun)this).photonView.RPC("RPC_EmergencyMeeting", (RpcTarget)0, new object[1] { actorNumber }); } [PunRPC] private void RPC_EmergencyMeeting(int reporterActor) { MyDebug.Log($"[MeetingController] Meeting requested by Actor {reporterActor}"); if ((Object)(object)_voteController == (Object)null) { Debug.LogError((object)"[MeetingController] ❌ VoteController not found on this GameObject!"); } MyDebug.Log("[MeetingController] RPC_EmergencyMeeting iAmAlive=" + ((Object)(object)localAvatar != (Object)null && ((Component)localAvatar).gameObject.activeInHierarchy)); if (PhotonNetwork.IsMasterClient) { _voteController.HostStartVote(reporterActor, -1); } } private void CacheLocalAvatar() { if (!((Object)(object)localAvatar != (Object)null)) { MyDebug.Log("[ReportController] CacheLocalAvatar()"); localAvatar = ((IEnumerable<PlayerAvatar>)Object.FindObjectsOfType<PlayerAvatar>()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar a) => a.photonView.IsMine)); } } internal void ResumeAfterVote() { MyDebug.Log("[MeetingController] ShowAll triggered from MeetingController::ResumeAfterVote"); UIButtonManager.Instance.ShowAll(); ((Selectable)meetingButton).interactable = false; meetingCooldown = ActiveSettings.Instance.EmergencyMeetingCooldownActive; } public void Cleanup() { MyDebug.Log("[MeetingController] GameDirector.instance.currentState=" + ((object)(gameState)(ref GameDirector.instance.currentState)).ToString()); MyDebug.Log("[MeetingController] SemiFunc.RunIsLevel()=" + SemiFunc.RunIsLevel()); MyDebug.Log("[MeetingController] clean up"); initialized = false; if ((Object)(object)meetingButton != (Object)null) { Object.Destroy((Object)(object)((Component)((Component)meetingButton).gameObject.transform.parent).gameObject); meetingButton = null; } } } [BepInPlugin("com.splitbrudis.impostormod.MenuPageLobbyPatch", "MenuPageLobbyPatch", "1.0.0")] public class MenuPageLobbyPatch : BaseUnityPlugin { private void Awake() { Object.DontDestroyOnLoad((Object)(object)this); Harmony.CreateAndPatchAll(typeof(MenuPageLobbyPatches), (string)null); } } internal static class MenuPageLobbyPatches { [HarmonyPostfix] [HarmonyPatch(typeof(MenuPageLobby), "Start")] private static void MenuPageLobby_Start_Postfix(MenuPageLobby __instance) { LobbyPopupController.Instance.JoinRoom(); } } public class ModManager : MonoBehaviour { public static MyGameManagerController MyGameManagerController; private static GameObject controllersGO; private ImpostorController impostorController; private VoteController voteController; private ReportController reportController; private MeetingController meetingController; private ActiveSettings activeSettings; private LobbyPopupController lobbyPopupController; private MyGameManagerController gameManagerController; private AvatarRPCReceiver avatarRPCReceiver; private UIButtonManager uiButtonManager; public bool ModEnabled; public bool mainGameInitialized = false; public void EnableMod() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (!((Object)(object)controllersGO != (Object)null)) { MyDebug.Log("[ModManager] Mod aktiviert – Erstelle GameControllers."); controllersGO = new GameObject("GameControllers"); Object.DontDestroyOnLoad((Object)(object)controllersGO); PhotonView val = controllersGO.AddComponent<PhotonView>(); if (!PhotonNetwork.AllocateViewID(val)) { Debug.LogError((object)"[ModManager] Failed to AllocateViewID!"); Object.Destroy((Object)(object)controllersGO); controllersGO = null; return; } MyDebug.Log($"[ModManager] Allocated controllersGO PhotonView.ViewID={val.ViewID}"); impostorController = controllersGO.AddComponent<ImpostorController>(); voteController = controllersGO.AddComponent<VoteController>(); reportController = controllersGO.AddComponent<ReportController>(); meetingController = controllersGO.AddComponent<MeetingController>(); activeSettings = controllersGO.AddComponent<ActiveSettings>(); lobbyPopupController = controllersGO.AddComponent<LobbyPopupController>(); gameManagerController = controllersGO.AddComponent<MyGameManagerController>(); avatarRPCReceiver = controllersGO.AddComponent<AvatarRPCReceiver>(); uiButtonManager = controllersGO.AddComponent<UIButtonManager>(); MyGameManagerController = gameManagerController; voteController._meetingController = meetingController; gameManagerController._voteController = voteController; ModEnabled = true; } } public void DisableMod() { if ((Object)(object)controllersGO != (Object)null) { MyDebug.Log("[ModManager] Mod deaktiviert – Zerstöre GameControllers."); CleanUp(); Object.Destroy((Object)(object)controllersGO); controllersGO = null; impostorController = null; voteController = null; reportController = null; meetingController = null; activeSettings = null; lobbyPopupController = null; gameManagerController = null; avatarRPCReceiver = null; MyGameManagerController = null; uiButtonManager = null; } ModEnabled = false; } internal void CleanUp() { if ((Object)(object)controllersGO == (Object)null) { return; } MyDebug.Log("[ModManager] Running controller Cleanup()..."); TryCallCleanup(impostorController); TryCallCleanup(voteController); TryCallCleanup(reportController); TryCallCleanup(meetingController); TryCallCleanup(MyGameManager.Instance); PhotonView component = controllersGO.GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null) { try { PhotonNetwork.RemoveRPCs(component); MyDebug.Log($"[ModManager] Removed buffered RPCs for controllersPV ViewID={component.ViewID}"); } catch (Exception arg) { Debug.LogWarning((object)$"[ModManager] Exception while removing buffered RPCs: {arg}"); } } mainGameInitialized = false; } private void TryCallCleanup(ICleanupable c) { if (c == null) { return; } try { c.Cleanup(); } catch (Exception arg) { Debug.LogError((object)$"Error during Cleanup() on {c.GetType().Name}: {arg}"); } } } public static class MyDebug { private static readonly bool debug; public static void Log(string message) { if (debug) { Log(message); } } } public class MyGameManager : MonoBehaviourPunCallbacks, ICleanupable { public bool gameOver = false; public int _impostorViewID; private static MyGameManager _instance; public bool IAmDead { get; private set; } public static MyGameManager Instance { get { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { MyDebug.Log("[MyGameManager] Instance getter: creating manager"); GameObject val = new GameObject("MyGameManager"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<MyGameManager>(); _instance.IAmDead = false; } return _instance; } } public void MarkMeDead() { IAmDead = true; } public void ResetRound() { MyDebug.Log("[MyGameManager] Resetting round state"); IAmDead = false; } public void Cleanup() { gameOver = false; IAmDead = false; _impostorViewID = -1; } } [RequireComponent(typeof(PhotonView))] public class MyGameManagerController : MonoBehaviourPunCallbacks { [CompilerGenerated] private sealed class <StopVotingInProgress>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MyGameManagerController <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StopVotingInProgress>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this._voteController.StopVotingInProgress(); 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(); } } public VoteController _voteController; public override void OnMasterClientSwitched(Player newMasterClient) { MyDebug.Log("[MyGameManager] Master client switched"); ModManager modManager = Object.FindObjectOfType<ModManager>(); if ((Object)(object)modManager != (Object)null) { modManager.CleanUp(); MyGameManager.Instance.gameOver = true; } } public override void OnPlayerLeftRoom(Player player) { MyDebug.Log("[MyGameManager] OnPlayerLeftRoom"); ModManager modManager = Object.FindObjectOfType<ModManager>(); if ((!((Object)(object)modManager != (Object)null) || modManager.mainGameInitialized) && PhotonNetwork.IsMasterClient && !MyGameManager.Instance.gameOver) { PlayerAvatar val = ((IEnumerable<PlayerAvatar>)Object.FindObjectsOfType<PlayerAvatar>()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar av) => av.photonView.Owner.ActorNumber == player.ActorNumber)); CheckWinConditionsAsHost(val.photonView.ViewID); } } public void OnPlayerKilled(int victimViewID) { if (!MyGameManager.Instance.gameOver) { MyDebug.Log($"[MyGameManager] Player killed: {victimViewID}"); bool flag = CheckWinConditionsAsHost(victimViewID); if ((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null) { Debug.LogError((object)"RPC_ShowVoteResultAnd photonView reference is null — can't send RPC"); } else { MyDebug.Log($"Sending RPC_ShowVoteResultAnd on photonView.ViewID={((MonoBehaviourPun)this).photonView.ViewID}"); } if (flag) { ((MonoBehaviourPun)this).photonView.RPC("RPC_ShowVoteResultAndThenGameOver", (RpcTarget)0, new object[2] { victimViewID, _voteController.votedPlayerIsGettingKilled }); } else if (_voteController.votedPlayerIsGettingKilled) { ((MonoBehaviourPun)this).photonView.RPC("RPC_ShowVoteResultAndThenContinue", (RpcTarget)0, new object[1] { victimViewID }); } } } [PunRPC] private void RPC_ShowVoteResultAndThenContinue(int victimViewID) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) PhotonView photonView = ((MonoBehaviourPun)this).photonView; MyDebug.Log($"Received RPC_EndGame for viewID {((photonView != null) ? photonView.ViewID : 0)}"); PhotonView val = PhotonView.Find(victimViewID); PlayerAvatar val2 = ((val != null) ? ((Component)val).GetComponent<PlayerAvatar>() : null); bool flag = (Object)(object)val2 != (Object)null && val2.photonView.ViewID == MyGameManager.Instance._impostorViewID; MyDebug.Log("[MyGameManager] ShowVoteResultAndThenContinue=" + (((Object)(object)val2 != (Object)null) ? val2.photonView.ViewID : (-1)) + ", is impostor=" + flag); string headerText = "Vote Result"; string text = (((Object)(object)val2 != (Object)null) ? SemiFunc.PlayerGetName(val2) : "No Name Found"); string bodyText = text + " was ejected. They were not the impostor."; Color red = Color.red; MyDebug.Log("[MyGameManager] RPC_AnnounceVoteResult open popUp"); MyDebug.Log("[MyGameManager] ShowVoteResultAndThenContinue, MenuManager.instance.currentMenuPage=" + (object)MenuManager.instance.currentMenuPage); PagePopUp(headerText, red, bodyText, "Continue", delegate { _voteController.ResumeAfterVoteResults(); }, closeThisPopup: true); ((MonoBehaviour)this).StartCoroutine(StopVotingInProgress()); } [IteratorStateMachine(typeof(<StopVotingInProgress>d__5))] private IEnumerator StopVotingInProgress() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StopVotingInProgress>d__5(0) { <>4__this = this }; } [PunRPC] private void RPC_ShowVoteResultAndThenGameOver(int victimViewID, bool lastPlayerVoted) { //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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) PhotonView photonView = ((MonoBehaviourPun)this).photonView; MyDebug.Log($"Received RPC_EndGame for viewID {((photonView != null) ? photonView.ViewID : 0)}"); bool flag = !lastPlayerVoted; MyGameManager.Instance.gameOver = true; bool flag2 = victimViewID == MyGameManager.Instance._impostorViewID; MyDebug.Log("[MyGameManager] ShowVoteResultAndThenGameOver=" + victimViewID + ", is impostor=" + flag2 + ", lastPlayerVoted=" + lastPlayerVoted); string headerText = (flag ? "No Players left" : "Vote Result"); PhotonView val = PhotonView.Find(victimViewID); PlayerAvatar val2 = ((val != null) ? ((Component)val).GetComponent<PlayerAvatar>() : null); string text = (((Object)(object)val2 != (Object)null) ? SemiFunc.PlayerGetName(val2) : "No Name Found"); string bodyText; Color headerColor; if (flag) { bodyText = text + " was killed."; headerColor = Color.red; } else if (flag2) { bodyText = text + " was ejected. They were the impostor!"; headerColor = Color.green; } else { bodyText = text + " was ejected. They were not the impostor."; headerColor = Color.red; } MyDebug.Log("[MyGameManager] ShowVoteResultAndThenGameOver, MenuManager.instance.currentMenuPage=" + (object)MenuManager.instance.currentMenuPage); PagePopUp(headerText, headerColor, bodyText, "Continue", delegate { }); } public void PagePopUp(string headerText, Color headerColor, string bodyText, string buttonText, Action onClick, bool closeThisPopup = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ModUtils.OpenPagePopUp(headerText, headerColor, bodyText, buttonText, onClick, allowTextOverflow: true, closeThisPopup); } private bool CheckWinConditionsAsHost(int playerViewID) { MyDebug.Log("Stored _impostorViewID = " + MyGameManager.Instance._impostorViewID); MyDebug.Log("CheckWinConditionsAsHost with playerViewID = " + playerViewID); if (playerViewID == MyGameManager.Instance._impostorViewID) { MyDebug.Log("[MyGameManager] Impostor left → crew victory!"); if ((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null) { Debug.LogError((object)"photonView reference is null — can't send RPC"); } else { MyDebug.Log($"Sending RPC RPC_EndGame on photonView.ViewID={((MonoBehaviourPun)this).photonView.ViewID}"); } MyGameManager.Instance.gameOver = true; ((MonoBehaviourPun)this).photonView.RPC("RPC_EndGame", (RpcTarget)0, new object[1] { true }); return true; } List<int> list = (from av in GameDirector.instance.PlayerList where !av.deadSet select av.photonView.ViewID).ToList(); Player[] playerList = PhotonNetwork.PlayerList; int num = GameDirector.instance.PlayerList.Count((PlayerAvatar av) => av.isDisabled); if (list.Count == 1 || playerList.Length == 1) { if ((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null) { Debug.LogError((object)"photonView reference is null — can't send RPC"); } else { MyDebug.Log($"Sending RPC RPC_EndGame on photonView.ViewID={((MonoBehaviourPun)this).photonView.ViewID}"); } Player p = playerList[0]; PhotonView val = ((IEnumerable<PhotonView>)Object.FindObjectsOfType<PhotonView>()).FirstOrDefault((Func<PhotonView, bool>)((PhotonView x) => x.CreatorActorNr == p.ActorNumber || x.OwnerActorNr == p.ActorNumber)); if ((Object)(object)val == (Object)null) { MyDebug.Log("Player " + p.NickName + " has no matching PhotonView on this client yet"); } MyGameManager.Instance.gameOver = true; if (((playerList.Length == 1) ? val.ViewID : list[0]) == MyGameManager.Instance._impostorViewID) { MyDebug.Log("[MyGameManager] Only impostor remains → impostor wins!"); ((MonoBehaviourPun)this).photonView.RPC("RPC_EndGame", (RpcTarget)0, new object[1] { false }); } else { MyDebug.Log("[MyGameManager] Only crew player remains → crew wins!"); ((MonoBehaviourPun)this).photonView.RPC("RPC_EndGame", (RpcTarget)0, new object[1] { true }); } return true; } MyDebug.Log("[MyGameManager] remaining1 count=" + list.Count); MyDebug.Log("[MyGameManager] playerList.Length=" + playerList.Length); MyDebug.Log("[MyGameManager] remaining2 count=" + num); return false; } } [HarmonyPatch(typeof(PlayerAvatar), "Start")] internal static class Patch_PlayerAvatar_Start { private static void Postfix(PlayerAvatar __instance) { if ((Object)(object)((Component)__instance).GetComponent<AvatarRPCReceiver>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<AvatarRPCReceiver>(); } } } public class PhotonDebug : MonoBehaviour { private void Start() { LogAllPhotonViews(); } [ContextMenu("LogPhotonViews")] public void LogAllPhotonViews() { PhotonView[] array = Object.FindObjectsOfType<PhotonView>(); MyDebug.Log($"--- PhotonViews on {PhotonNetwork.NickName} (Actor {PhotonNetwork.LocalPlayer.ActorNumber}) ---"); PhotonView[] array2 = array; foreach (PhotonView val in array2) { MyDebug.Log($"PV name:{((Object)((Component)val).gameObject).name} viewID:{val.ViewID} creator:{val.CreatorActorNr} owner:{val.OwnerActorNr}"); } } } public class PopupManager : MonoBehaviour { [CompilerGenerated] private sealed class <CleanupLoop>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PopupManager <>4__this; private object <>s__1; private bool <>s__2; private int <i>5__3; private REPOPopupPage <popup>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CleanupLoop>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>s__1 = null; <popup>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } <>s__1 = <>4__this._lock; <>s__2 = false; try { Monitor.Enter(<>s__1, ref <>s__2); <i>5__3 = <>4__this._popups.Count - 1; while (<i>5__3 >= 0) { <popup>5__4 = <>4__this._popups[<i>5__3]; if ((Object)(object)<popup>5__4 == (Object)null || (Object)(object)<popup>5__4.menuPage == (Object)null || (Object)(object)((Component)<popup>5__4).gameObject == (Object)null) { <>4__this._popups.RemoveAt(<i>5__3); } <popup>5__4 = null; <i>5__3--; } } finally { if (<>s__2) { Monitor.Exit(<>s__1); } } <>s__1 = null; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OpenManagedPopupCoroutine>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Func<REPOPopupPage> createPopupFactory; public Action<REPOPopupPage> onOpened; public PopupManager <>4__this; private REPOPopupPage <popup>5__1; private Exception <ex>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OpenManagedPopupCoroutine>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <popup>5__1 = null; <ex>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.CloseAll(); <>2__current = (object)new WaitForSeconds(0.05f); <>1__state = 1; return true; case 1: <>1__state = -1; <popup>5__1 = null; try { <popup>5__1 = createPopupFactory(); } catch (Exception ex) { <ex>5__2 = ex; Debug.LogError((object)$"[PopupManager] OpenManagedPopup: factory threw: {<ex>5__2}"); throw; } if ((Object)(object)<popup>5__1 != (Object)null) { <>4__this.RegisterPopup(<popup>5__1); onOpened?.Invoke(<popup>5__1); } else { Debug.LogWarning((object)"[PopupManager] OpenManagedPopup: factory returned null popup"); } 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 PopupManager _instance; private readonly List<REPOPopupPage> _popups = new List<REPOPopupPage>(); private readonly object _lock = new object(); private Coroutine _cleanupCoroutine; public static PopupManager Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("PopupManager"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<PopupManager>(); } return _instance; } } private void Awake() { if ((Object)(object)_instance == (Object)null) { _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } else if ((Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _cleanupCoroutine = ((MonoBehaviour)this).StartCoroutine(CleanupLoop()); } [IteratorStateMachine(typeof(<CleanupLoop>d__7))] private IEnumerator CleanupLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CleanupLoop>d__7(0) { <>4__this = this }; } private void OnDestroy() { if (_cleanupCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_cleanupCoroutine); } } public void RegisterPopup(REPOPopupPage popup) { if ((Object)(object)popup == (Object)null) { return; } lock (_lock) { if (!_popups.Contains(popup)) { _popups.Add(popup); } } } public void UnregisterPopup(REPOPopupPage popup) { if ((Object)(object)popup == (Object)null) { return; } lock (_lock) { _popups.Remove(popup); } } public void CloseAll(bool animate = true) { lock (_lock) { for (int num = _popups.Count - 1; num >= 0; num--) { REPOPopupPage val = _popups[num]; try { if ((Object)(object)val != (Object)null && (Object)(object)val.menuPage != (Object)null) { val.ClosePage(animate); } } catch (Exception arg) { Debug.LogWarning((object)$"[PopupManager] CloseAll: failed closing popup: {arg}"); } } _popups.Clear(); } } public void ClosePopup(REPOPopupPage popup, bool animate = true) { if ((Object)(object)popup == (Object)null) { return; } lock (_lock) { try { if ((Object)(object)popup.menuPage != (Object)null) { popup.ClosePage(animate); } } catch (Exception arg) { Debug.LogWarning((object)$"[PopupManager] ClosePopup error: {arg}"); } _popups.Remove(popup); } } public REPOPopupPage[] GetOpenPopups() { lock (_lock) { return _popups.Where((REPOPopupPage p) => (Object)(object)p != (Object)null).ToArray(); } } public void OpenManagedPopupDelayed(Func<REPOPopupPage> createPopupFactory, Action<REPOPopupPage> onOpened) { if (createPopupFactory == null) { throw new ArgumentNullException("createPopupFactory"); } ((MonoBehaviour)this).StartCoroutine(OpenManagedPopupCoroutine(createPopupFactory, onOpened)); } [IteratorStateMachine(typeof(<OpenManagedPopupCoroutine>d__15))] public IEnumerator OpenManagedPopupCoroutine(Func<REPOPopupPage> createPopupFactory, Action<REPOPopupPage> onOpened) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OpenManagedPopupCoroutine>d__15(0) { <>4__this = this, createPopupFactory = createPopupFactory, onOpened = onOpened }; } } [HarmonyPatch(typeof(PunManager), "Start")] internal static class PunManagerPatch { private static void Postfix(PunManager __instance) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if ((Object)(object)Object.FindObjectOfType<ModManager>() != (Object)null) { MyDebug.Log("ModManager already exists → skipping creation."); return; } GameObject val = new GameObject("ModManager"); Object.DontDestroyOnLoad((Object)(object)val); MyDebug.Log("ADD ModManager -> created once"); ModManager modManager = val.AddComponent<ModManager>(); modManager.EnableMod(); } } [BepInPlugin("com.splitbrudis.impostormod.REPOImpostorMod", "REPOImpostorMod", "1.0.0")] public class REPOImpostorMod : BaseUnityPlugin { internal static REPOImpostorMod Instance; private ConfigEntry<int> killCooldown; private ConfigEntry<int> emergencyMeetingCooldown; private ConfigEntry<int> killRange; private ConfigEntry<int> voteTimerSeconds; private ConfigEntry<int> emergencyMeetingsPerPlayer; private ConfigEntry<KeyCode> reportKey; private ConfigEntry<KeyCode> meetingKey; private ConfigEntry<KeyCode> killKey; private ConfigEntry<bool> modEnabled; public bool ModEnabled => modEnabled.Value; public int KillCooldown => killCooldown.Value; public int EmergencyMeetingCooldown => emergencyMeetingCooldown.Value; public int KillRange => killRange.Value; public int VoteTimerSeconds => voteTimerSeconds.Value; public int EmergencyMeetingsPerPlayer => emergencyMeetingsPerPlayer.Value; public KeyCode ReportKey => reportKey.Value; public KeyCode MeetingKey => meetingKey.Value; public KeyCode KillKey => killKey.Value; private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown MyDebug.Log("[REPOImpostorMod] REPOImpostorMod Awake"); Instance = this; InitBindings(); Harmony val = new Harmony("com.splitbrudis.impostor"); val.PatchAll(((object)this).GetType().Assembly); } public void InitBindings() { //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ModEnabled", true, "Enable or disable the REPO Impostor Mod."); killCooldown = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "KillCooldownSeconds", 2, "How many seconds between kills. 30 is default"); killRange = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "killRangeSeconds", 2, "Range for kills. 2 is default"); voteTimerSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "VoteTimerSeconds", 100, "How many seconds players have to cast a vote. 60 is default"); emergencyMeetingsPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "EmergencyMeetingsPerPlayer", 1, "How many emergency meetings a players can cast a vote. 1 is default"); emergencyMeetingCooldown = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "EmergencyMeetingCooldown", 10, "How many seconds between emergency meetings. 30 is default"); MyDebug.Log($"Kill CD = {killCooldown.Value}s"); MyDebug.Log($"Vote Timer = {voteTimerSeconds.Value}s"); reportKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ReportKey", (KeyCode)114, "Key to report a body"); meetingKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "MeetingKey", (KeyCode)101, "Key to call an emergency meeting"); killKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "KillKey", (KeyCode)107, "Key to kill as impostor"); KeyCode value = meetingKey.Value; MyDebug.Log("meetingKey=" + ((object)(KeyCode)(ref value)).ToString()); } internal void SaveConfig(ActiveSettings settings) { modEnabled.Value = settings.ModEnabledActive; killCooldown.Value = settings.KillCooldownActive; killRange.Value = settings.KillRangeActive; voteTimerSeconds.Value = settings.VoteTimerSecondsActive; emergencyMeetingsPerPlayer.Value = settings.EmergencyMeetingsPerPlayerActive; emergencyMeetingCooldown.Value = settings.EmergencyMeetingCooldownActive; MyDebug.Log("[SaveConfig] Host settings saved to config."); } } [BepInPlugin("com.splitbrudis.impostormod.RepoPlayerDeathPatch", "RepoPlayerDeathPatch", "1.0.0")] public class RepoPlayerDeathPatch : BaseUnityPlugin { private void Awake() { Harmony val = Harmony.CreateAndPatchAll(typeof(PlayerAvatarPatches), (string)null); MyDebug.Log("[Patch] Applied patches: " + val.Id); } } internal static class PlayerAvatarPatches { [HarmonyPrefix] [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")] private static bool Prefix_PlayerDeathDone(PlayerAvatar __instance) { return true; } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")] private static void Postfix_PlayerDeathDone(PlayerAvatar __instance) { MyDebug.Log("[Patch] >>> Entering PlayerDeathDone Postfix <<<"); if (PhotonNetwork.IsMasterClient) { ModManager.MyGameManagerController.OnPlayerKilled(__instance.photonView.ViewID); } MyDebug.Log($"[Patch] Post-death logic for player: ViewID={__instance.photonView.ViewID}, Actor={__instance.photonView.Owner.ActorNumber}"); } } [RequireComponent(typeof(PhotonView))] public class ReportController : MonoBehaviourPunCallbacks, ICleanupable { public float reportRange = 4f; private Button reportButton; private PlayerAvatar localAvatar; private bool initialized = false; private VoteController _voteController; private Canvas runCanvas; private MenuPlayerListed runPlayerListed; [PunRPC] public void RPC_ReportBody(int reporterActor, int reportedAvatarViewID) { MyDebug.Log($"[ReportRPCHandler] actor {reporterActor} reported Body: {reportedAvatarViewID}"); if ((Object)(object)_voteController == (Object)null) { Debug.LogError((object)"[ReportRPCHandler] ❌ VoteController not found on this GameObject!"); } ((Behaviour)PlayerController.instance).enabled = false; MyDebug.Log("[ReportController] RPC_ReportBody iAmAlive=" + ((Object)(object)localAvatar != (Object)null && ((Component)localAvatar).gameObject.activeInHierarchy)); if (PhotonNetwork.IsMasterClient) { _voteController.HostStartVote(reporterActor, reportedAvatarViewID); } } private void Awake() { _voteController = ((Component)this).GetComponent<VoteController>(); if ((Object)(object)_voteController == (Object)null) { Debug.LogError((object)"[ReportController] Couldn’t find VoteController!");