Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of TPVoting v1.3.0
TPVoting.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using EntityStates; using MonoMod.RuntimeDetour; using On.RoR2; using R2API.Utils; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TPVoting")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f7c41176495831919350cccc9304a33085d7e283")] [assembly: AssemblyProduct("TPVoting")] [assembly: AssemblyTitle("TPVoting")] [assembly: AssemblyVersion("1.0.0.0")] namespace TPVoting; public static class ChatHelper { private const string GrayColor = "7e91af"; private const string RedColor = "ff0000"; private const string YellowColor = "ffff00"; private const string GreenColor = "32cd32"; private const string SilverColor = "c0c0c0"; public static void UserIsReady(string userName, int numberOfUsersWhoVoted, int numberOfVotingUsers) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown string baseToken = string.Format("<color=#{0}>{1}</color> is ready! <color=#{2}>({3}/{4})</color>", "32cd32", userName, "7e91af", numberOfUsersWhoVoted, numberOfVotingUsers); Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = baseToken }); } public static void TPUnlocked() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown string baseToken = "<color=#ff0000>Teleporter</color> is unlocked! <color=#32cd32>Players are free to start it.</color>"; Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = baseToken }); } public static void PlayersNotReady() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown string baseToken = "<color=#ff0000>Players are not ready.</color> Vote by writting <color=#c0c0c0>\"r\"</color> in chat."; Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = baseToken }); } public static void VotingInstruction() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown string baseToken = "Vote <color=#ff0000>Teleporter</color> by writting <color=#c0c0c0>\"r\"</color> in chat."; Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = baseToken }); } public static void TPCountdown(uint unlockTime) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown string baseToken = string.Format("Starting <color=#{0}>Teleporter</color> unlock <color=#{1}>countdown!</color> <color=#{2}>({3} seconds left)</color>", "ff0000", "ffff00", "7e91af", unlockTime); Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = baseToken }); } } public static class UsersHelper { public static NetworkUser GetUser(Interactor activator) { CharacterBody body = ((Component)activator).GetComponent<CharacterBody>(); return ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)((NetworkUser u) => (Object)(object)u.master.GetBody() == (Object)(object)body)); } public static NetworkUser GetUser(CharacterMaster player) { return ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)((NetworkUser u) => (Object)(object)u.master == (Object)(object)player)); } public static bool IsOneUserOnly() { return NetworkUser.readOnlyInstancesList.Count <= 1; } } public class TPLocker : NetworkBehaviour { public delegate bool LockedTPInteractibility(NetworkUser user); public delegate void LockedTPInteractionAttempt(NetworkUser interactingUser); public delegate Interactability orig_GetInteractability(GenericInteraction self, Interactor activator); public delegate void orig_OnInteractionBegin(GenericInteraction self, Interactor activator); public bool IsTPUnlocked = true; public Hook hook_GetInteractability; public Hook hook_OnInteractionBegin; public LockedTPInteractibility IsLockedTPInteractable { get; set; } = (NetworkUser user) => true; public event LockedTPInteractionAttempt OnLockedTPInteractionAttempt; public void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0061: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a0: Expected O, but got Unknown TeleporterInteraction.GetInteractability += new hook_GetInteractability(TeleporterInteraction_GetInteractability); TeleporterInteraction.OnInteractionBegin += new hook_OnInteractionBegin(TeleporterInteraction_OnInteractionBegin); hook_GetInteractability = new Hook((MethodBase)typeof(GenericInteraction).GetMethod("RoR2.IInteractable.GetInteractability", BindingFlags.Instance | BindingFlags.NonPublic), typeof(TPLocker).GetMethod("GenericInteraction_GetInteractability"), (object)this, default(HookConfig)); hook_OnInteractionBegin = new Hook((MethodBase)typeof(GenericInteraction).GetMethod("RoR2.IInteractable.OnInteractionBegin", BindingFlags.Instance | BindingFlags.NonPublic), typeof(TPLocker).GetMethod("GenericInteraction_OnInteractionBegin"), (object)this, default(HookConfig)); } public void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown TeleporterInteraction.GetInteractability -= new hook_GetInteractability(TeleporterInteraction_GetInteractability); TeleporterInteraction.OnInteractionBegin -= new hook_OnInteractionBegin(TeleporterInteraction_OnInteractionBegin); hook_GetInteractability.Dispose(); hook_OnInteractionBegin.Dispose(); } private Interactability TeleporterInteraction_GetInteractability(orig_GetInteractability orig, TeleporterInteraction self, Interactor activator) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) return GetInteractability<orig_GetInteractability, TeleporterInteraction>(orig, self, activator); } private void TeleporterInteraction_OnInteractionBegin(orig_OnInteractionBegin orig, TeleporterInteraction self, Interactor activator) { OnInteractionBegin<orig_OnInteractionBegin, TeleporterInteraction>(orig, self, activator); } public Interactability GenericInteraction_GetInteractability(orig_GetInteractability orig, GenericInteraction self, Interactor activator) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)self).name.ToLower().Contains("portal")) { orig(self, activator); } return GetInteractability<orig_GetInteractability, GenericInteraction>(orig, self, activator); } public void GenericInteraction_OnInteractionBegin(orig_OnInteractionBegin orig, GenericInteraction self, Interactor activator) { if (!((Object)self).name.ToLower().Contains("portal")) { orig(self, activator); } OnInteractionBegin<orig_OnInteractionBegin, GenericInteraction>(orig, self, activator); } private Interactability GetInteractability<ORIG, SELF>(ORIG orig, SELF self, Interactor activator) where ORIG : Delegate { //IL_0043: Unknown result type (might be due to invalid IL or missing references) NetworkUser user = UsersHelper.GetUser(activator); if (!IsTPUnlocked && (!Object.op_Implicit((Object)(object)user) || !IsLockedTPInteractable(user))) { return (Interactability)1; } return (Interactability)orig.DynamicInvoke(self, activator); } private void OnInteractionBegin<ORIG, SELF>(ORIG orig, SELF self, Interactor activator) where ORIG : Delegate { if (IsTPUnlocked) { orig.DynamicInvoke(self, activator); return; } NetworkUser user = UsersHelper.GetUser(activator); if (Object.op_Implicit((Object)(object)user)) { this.OnLockedTPInteractionAttempt?.Invoke(user); } } } public class TPVotingController : NetworkBehaviour { public delegate void TPVotingStarted(); public delegate void TPVotingEnded(); private VotingMachine<NetworkUserId> votingMachine = new VotingMachine<NetworkUserId>(); private IEnumerator majorityTPVotingTimer; private bool isMajorityTPVotingTimerRunning; public event TPVotingStarted OnTPVotingStarted; public event TPVotingEnded OnTPVotingEnded; public bool IsVotingStarted() { return votingMachine.IsVotingStarted; } public bool HasUserVoted(NetworkUser user) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)user)) { return votingMachine.CheckIfVoted(user.id); } return false; } public bool Vote(NetworkUser user) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)user) && votingMachine.IsVotingStarted) { return votingMachine.Vote(user.id); } return false; } public void StartVoting(bool showInstruction = true) { if (!votingMachine.IsVotingStarted) { votingMachine.StartVoting(NetworkUser.readOnlyInstancesList.Select((NetworkUser l) => l.id).ToList()); if (showInstruction) { ((MonoBehaviour)this).StartCoroutine(ShowVotingInstruction()); } } static IEnumerator ShowVotingInstruction() { yield return (object)new WaitForSeconds(3f); ChatHelper.VotingInstruction(); } } public void EndVoting() { if (votingMachine.IsVotingStarted) { votingMachine.EndVoting(); } } public void Awake() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown votingMachine.CheckVotingEndCondition = delegate(VotingMachine<NetworkUserId> votingMachine) { uint unlockTime; if (votingMachine.CheckIfHalfOrMoreVoted() && !isMajorityTPVotingTimerRunning) { unlockTime = PluginConfig.MajorityVotesCountdownTime.Value; ChatHelper.TPCountdown(unlockTime); ((MonoBehaviour)this).StartCoroutine(majorityTPVotingTimer = WaitAndEndVoting()); } return votingMachine.CheckIfAllVoted() || votingMachine.CheckIfThereIsOnlyOneVoter(); IEnumerator WaitAndEndVoting() { isMajorityTPVotingTimerRunning = true; yield return (object)new WaitForSeconds((float)unlockTime); votingMachine.EndVoting(); isMajorityTPVotingTimerRunning = false; } }; votingMachine.OnVotingStarted += VotingMachine_OnVotingStarted; votingMachine.OnVotingEnded += VotingMachine_OnVotingEnded; votingMachine.OnVoterVoted += VotingMachine_OnVoterVoted; CharacterMaster.OnBodyDeath += new hook_OnBodyDeath(CharacterMaster_OnBodyDeath); NetworkUser.OnDestroy += new hook_OnDestroy(NetworkUser_OnDestroy); Chat.SendBroadcastChat_ChatMessageBase += new hook_SendBroadcastChat_ChatMessageBase(Chat_SendBroadcastChat_ChatMessageBase); } public void OnDestroy() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown votingMachine.OnVotingStarted -= VotingMachine_OnVotingStarted; votingMachine.OnVotingEnded -= VotingMachine_OnVotingEnded; votingMachine.OnVoterVoted -= VotingMachine_OnVoterVoted; CharacterMaster.OnBodyDeath -= new hook_OnBodyDeath(CharacterMaster_OnBodyDeath); NetworkUser.OnDestroy -= new hook_OnDestroy(NetworkUser_OnDestroy); Chat.SendBroadcastChat_ChatMessageBase -= new hook_SendBroadcastChat_ChatMessageBase(Chat_SendBroadcastChat_ChatMessageBase); } private void VotingMachine_OnVotingStarted() { this.OnTPVotingStarted?.Invoke(); } private void VotingMachine_OnVotingEnded() { ((MonoBehaviour)this).StopCoroutine(majorityTPVotingTimer); isMajorityTPVotingTimerRunning = false; this.OnTPVotingEnded?.Invoke(); } private void VotingMachine_OnVoterVoted(NetworkUserId voterID) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) NetworkUser val = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)delegate(NetworkUser l) { //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_000a: Unknown result type (might be due to invalid IL or missing references) NetworkUserId id = l.id; return ((NetworkUserId)(ref id)).Equals(voterID); }); if (Object.op_Implicit((Object)(object)val)) { IReadOnlyDictionary<NetworkUserId, bool> votes = votingMachine.Votes; ChatHelper.UserIsReady(val.userName, votes.Count((KeyValuePair<NetworkUserId, bool> ks) => ks.Value), votes.Count); } } private void CharacterMaster_OnBodyDeath(orig_OnBodyDeath orig, CharacterMaster self, CharacterBody body) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, body); if (votingMachine.IsVotingStarted && PluginConfig.UserAutoVoteOnDeath.Value && self.IsDeadAndOutOfLivesServer()) { NetworkUser user = UsersHelper.GetUser(self); if (Object.op_Implicit((Object)(object)user)) { votingMachine.Vote(user.id); } } } private void NetworkUser_OnDestroy(orig_OnDestroy orig, NetworkUser self) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (votingMachine.IsVotingStarted) { votingMachine.RemoveVoter(self.id); } } private void Chat_SendBroadcastChat_ChatMessageBase(orig_SendBroadcastChat_ChatMessageBase orig, ChatMessageBase message) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!votingMachine.IsVotingStarted) { orig.Invoke(message); return; } UserChatMessage val = (UserChatMessage)(object)((message is UserChatMessage) ? message : null); if (val != null) { NetworkUser component = val.sender.GetComponent<NetworkUser>(); if (Object.op_Implicit((Object)(object)component)) { string message2 = val.text.ToLower().Trim(); if (CheckIfReadyMessage(message2) && votingMachine.Vote(component.id)) { return; } } } orig.Invoke(message); } private bool CheckIfReadyMessage(string message) { return PluginConfig.PlayerIsReadyMessages.Value.Split(',').Contains(message); } } public class TPVotingSystem : NetworkBehaviour { private TPLocker tpLocker; public TPVotingController TPVotingController { get; private set; } public bool IsTPUnlocked() { return tpLocker.IsTPUnlocked; } public void Awake() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown TPVotingController = ((Component)this).gameObject.AddComponent<TPVotingController>(); TPVotingController.OnTPVotingStarted += TPVotingController_OnTPVotingStarted; TPVotingController.OnTPVotingEnded += TPVotingController_OnTPVotingEnded; tpLocker = ((Component)this).gameObject.AddComponent<TPLocker>(); tpLocker.IsLockedTPInteractable = (NetworkUser user) => !TPVotingController.HasUserVoted(user); tpLocker.OnLockedTPInteractionAttempt += TpLocker_OnLockedTPInteractionAttempt; Run.OnServerSceneChanged += new hook_OnServerSceneChanged(Run_OnServerSceneChanged); ChargedState.OnEnter += new hook_OnEnter(TeleporterInteraction_ChargedState_OnEnter); } public void OnDestroy() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown TPVotingController.OnTPVotingStarted -= TPVotingController_OnTPVotingStarted; TPVotingController.OnTPVotingEnded -= TPVotingController_OnTPVotingEnded; Object.Destroy((Object)(object)TPVotingController); tpLocker.OnLockedTPInteractionAttempt -= TpLocker_OnLockedTPInteractionAttempt; Object.Destroy((Object)(object)tpLocker); Run.OnServerSceneChanged -= new hook_OnServerSceneChanged(Run_OnServerSceneChanged); ChargedState.OnEnter -= new hook_OnEnter(TeleporterInteraction_ChargedState_OnEnter); } private void TPVotingController_OnTPVotingStarted() { tpLocker.IsTPUnlocked = false; } private void TPVotingController_OnTPVotingEnded() { tpLocker.IsTPUnlocked = true; ChatHelper.TPUnlocked(); } private void TpLocker_OnLockedTPInteractionAttempt(NetworkUser interactingUser) { if (!TPVotingController.Vote(interactingUser)) { ChatHelper.PlayersNotReady(); } } private void Run_OnServerSceneChanged(orig_OnServerSceneChanged orig, Run self, string sceneName) { orig.Invoke(self, sceneName); TryStartVoting(showInstruction: true); } private void TeleporterInteraction_ChargedState_OnEnter(orig_OnEnter orig, BaseState self) { orig.Invoke(self); if (PluginConfig.VoteAfterTPEvent.Value) { TryStartVoting(showInstruction: false); } } private void TryStartVoting(bool showInstruction) { tpLocker.IsTPUnlocked = true; TPVotingController.EndVoting(); if (!UsersHelper.IsOneUserOnly() && CheckIfCurrentStageQualifyForTPVoting()) { TPVotingController.StartVoting(showInstruction); } } private bool CheckIfCurrentStageQualifyForTPVoting() { return !PluginGlobals.IgnoredStages.Contains(SceneCatalog.GetSceneDefForCurrentScene().baseSceneName); } } public class VotingMachine<VoterID> { public delegate bool VotingEndCondition(VotingMachine<VoterID> votingMachine); public delegate void VotingUpdated(); public delegate void VotingStarted(); public delegate void VotingEnded(); public delegate void VoterVoted(VoterID voterID); public delegate void VoterRemoved(VoterID voterID); private Dictionary<VoterID, bool> votes = new Dictionary<VoterID, bool>(); public IReadOnlyDictionary<VoterID, bool> Votes => new ReadOnlyDictionary<VoterID, bool>(votes); public bool IsVotingStarted { get; private set; } public VotingEndCondition CheckVotingEndCondition { get; set; } = (VotingMachine<VoterID> votingMachine) => votingMachine.CheckIfAllVoted(); public event VotingUpdated OnVotingUpdated; public event VotingStarted OnVotingStarted; public event VotingEnded OnVotingEnded; public event VoterVoted OnVoterVoted; public event VoterRemoved OnVoterRemoved; public void StartVoting(IReadOnlyCollection<VoterID> voterIDs) { votes.Clear(); foreach (VoterID voterID in voterIDs) { votes[voterID] = false; } IsVotingStarted = true; this.OnVotingStarted?.Invoke(); PostVotingUpdate(); } public void EndVoting() { if (!IsVotingStarted) { Debug.LogWarning((object)"VotingMachine::EndVoting: Trying to end voting while there is no voting started"); return; } votes.Clear(); IsVotingStarted = false; this.OnVotingEnded?.Invoke(); PostVotingUpdate(); } public bool Vote(VoterID voterID) { if (!IsVotingStarted) { Debug.LogWarning((object)"VotingMachine::Vote: Trying to set vote while voting is not started"); return false; } if (votes.ContainsKey(voterID) && !votes[voterID]) { votes[voterID] = true; this.OnVoterVoted?.Invoke(voterID); PostVotingUpdate(); return true; } Debug.LogWarning((object)$"VotingMachine::Vote: Failed to find voter ID {voterID} in voter list"); return false; } public bool RemoveVoter(VoterID voterID) { if (!IsVotingStarted) { return false; } if (votes.ContainsKey(voterID)) { votes.Remove(voterID); this.OnVoterRemoved?.Invoke(voterID); PostVotingUpdate(); return true; } return false; } private void PostVotingUpdate() { this.OnVotingUpdated?.Invoke(); if (IsVotingStarted && CheckVotingEndCondition(this)) { EndVoting(); } } public bool CheckIfVoted(VoterID voterID) { bool value; return votes.TryGetValue(voterID, out value) && value; } public bool CheckIfAllVoted() { return votes.All((KeyValuePair<VoterID, bool> kv) => kv.Value); } public bool CheckIfThereIsOnlyOneVoter() { return votes.Count == 1; } public bool CheckIfHalfOrMoreVoted() { return votes.Count((KeyValuePair<VoterID, bool> kv) => kv.Value) >= Mathf.CeilToInt((float)votes.Count / 2f); } } internal class PluginConfig { public static ConfigEntry<string> PlayerIsReadyMessages; public static ConfigEntry<string> IgnoredGameModes; public static ConfigEntry<uint> MajorityVotesCountdownTime; public static ConfigEntry<bool> UserAutoVoteOnDeath; public static ConfigEntry<bool> VoteAfterTPEvent; } public static class PluginGlobals { public static List<string> IgnoredStages = new List<string> { "arena", "moon", "moon2", "limbo", "outro", "voidraid" }; } [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.Mordrog.TPVoting", "TPVoting", "1.2.3")] public class TPVotingPlugin : BaseUnityPlugin { public const string ModVer = "1.2.3"; public const string ModName = "TPVoting"; public const string ModGuid = "com.Mordrog.TPVoting"; public TPVotingSystem TPVotingSystem { get; private set; } public TPVotingPlugin() { InitConfig(); } public void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Run.Awake += new hook_Awake(Run_Awake); Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy); } private void Run_Awake(orig_Awake orig, Run self) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (!PluginConfig.IgnoredGameModes.Value.Contains(GameModeCatalog.GetGameModeName(self.gameModeIndex))) { TPVotingSystem = ((Component)this).gameObject.AddComponent<TPVotingSystem>(); } } private void Run_OnDestroy(orig_OnDestroy orig, Run self) { orig.Invoke(self); if (Object.op_Implicit((Object)(object)TPVotingSystem)) { Object.Destroy((Object)(object)TPVotingSystem); } } private void InitConfig() { PluginConfig.PlayerIsReadyMessages = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "PlayerIsReadyMessages", "r,rdy,ready", "The message the player has to write in the chat to confirm they are ready. Values must be separated by comma."); PluginConfig.IgnoredGameModes = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "IgnoredGameModes", "InfiniteTowerRun", "Gamemode in which tp voting should not work."); PluginConfig.MajorityVotesCountdownTime = ((BaseUnityPlugin)this).Config.Bind<uint>("Settings", "MajorityVotesCountdownTime", 30u, "Countdown in seconds to unlock the teleporter when half or most of the players are ready."); PluginConfig.UserAutoVoteOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "UserAutoVoteOnDeath", true, "Should players auto vote tp when they die."); PluginConfig.VoteAfterTPEvent = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "VoteAfterTPEvent", false, "Should tp voting also be activated after tp event."); } }