Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of TPVotingExpanded v0.1.1
TPVoting.dll
Decompiled 4 months 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.Bootstrap; using BepInEx.Configuration; using MonoMod.RuntimeDetour; using On.RoR2; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using UnityEngine; using UnityEngine.Networking; [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("TPVoting")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b3964ee0c4d0768a5c295f86fecb5b5e133e4d0e")] [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"; private static readonly string ReadyMessages = PluginConfig.CustomReadyMessages.Value; public static void UserIsReady(string player, int votes, int total) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown string text = ""; text = (string.IsNullOrEmpty(ReadyMessages) ? string.Format("<color=#{0}>{1}</color> is ready! <color=#{2}>({3}/{4})</color>", "32cd32", player, "7e91af", votes, total) : (ReadyMessages.Replace("{user}", "<color=#32cd32>" + player + "</color>").Replace("{votes}", string.Format("<color=#{0}>({1}</color>", "7e91af", votes)).Replace("{total}", string.Format("<color=#{0}>/{1})</color>", "7e91af", total)) ?? "")); Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = text }); } public static void TPUnlocked() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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(int unlockTime) { //IL_0033: 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_0044: 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 void DebugMessage(string debug) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown string baseToken = "<color=#c0c0c0>[TPVoting] " + debug + "</color>"; 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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)orig.DynamicInvoke(self, activator); } return (Interactability)1; } 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_0010: Unknown result type (might be due to invalid IL or missing references) return Object.op_Implicit((Object)(object)user) && votingMachine.CheckIfVoted(user.id); } public bool Vote(NetworkUser user) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) return Object.op_Implicit((Object)(object)user) && votingMachine.IsVotingStarted && votingMachine.Vote(user.id); } 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(); if (PluginConfig.ShowImportantConfigs.Value) { ChatHelper.DebugMessage("Important Configs for TP Voting:\nReady message options: " + PluginConfig.PlayerIsReadyMessages.Value + "\n" + $"Majority Votes Percentage: {PluginConfig.PercentageOfTotal.Value}%\n" + $"User Auto Vote On Death: {PluginConfig.UserAutoVoteOnDeath.Value}\n" + $"Vote after TP: {PluginConfig.VoteAfterTPEvent.Value}" + $"Display Important Configs (this message): {PluginConfig.ShowImportantConfigs.Value}"); } } } public void EndVoting() { if (votingMachine.IsVotingStarted) { votingMachine.EndVoting(); } } public void Awake() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown votingMachine.CheckVotingEndCondition = delegate(VotingMachine<NetworkUserId> votingMachine) { int unlockTime; if (votingMachine.CheckIfRequiredVoted() && !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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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 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_0052: 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_0025: 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_006f: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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); TeleporterInteraction.onTeleporterChargedGlobal += OnTeleporterChargedGlobal; } public void OnDestroy() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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); TeleporterInteraction.onTeleporterChargedGlobal -= OnTeleporterChargedGlobal; } 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 OnTeleporterChargedGlobal(TeleporterInteraction teleporterInteraction) { 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 CheckIfRequiredVoted() { int num = Mathf.CeilToInt(PluginConfig.PercentageOfTotal.Value / 100f); int num2 = Mathf.CeilToInt((float)(votes.Count((KeyValuePair<VoterID, bool> kv) => kv.Value) / votes.Count)); if (num2 >= num) { return true; } Debug.Log((object)$"VotingMachine::CheckIfRequiredVoted: Not enough votes. Required: {num}, Current: {num2}"); return false; } } internal class PluginConfig { public static ConfigEntry<string> PlayerIsReadyMessages; public static ConfigEntry<string> IgnoredGameModes; public static ConfigEntry<string> CustomReadyMessages; public static ConfigEntry<int> MajorityVotesCountdownTime; public static ConfigEntry<float> PercentageOfTotal; public static ConfigEntry<bool> UserAutoVoteOnDeath; public static ConfigEntry<bool> VoteAfterTPEvent; public static ConfigEntry<bool> ShowImportantConfigs; } 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.Ehseezed.TPVotingExpanded", "TPVotingExpanded", "0.1.0")] public class TPVotingPlugin : BaseUnityPlugin { public const string ModVer = "0.1.0"; public const string ModName = "TPVotingExpanded"; public const string ModGuid = "com.Ehseezed.TPVotingExpanded"; public TPVotingSystem TPVotingSystem { get; private set; } public TPVotingPlugin() { InitConfig(); } public void Awake() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0014: 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. Values must be separated by comma. Possible values: 'InfiniteTowerRun', 'EclipseRun', 'ClassicRun', 'WeeklyRun'"); PluginConfig.CustomReadyMessages = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "CustomReadyMessages", "{user} thinks your taking too long! ({votes}/{total})", "The message that appears in chat upon readying. Leave blank for default message. Use {user} for player name, {votes} for number of votes and {total} for total number of players."); PluginConfig.MajorityVotesCountdownTime = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "MajorityVotesCountdownTime", 30, "Countdown in seconds to unlock the teleporter when 'majority' of the players are ready."); PluginConfig.PercentageOfTotal = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "PercentageOfTotal", 100f, "Percentage of total players that need to be ready to start the countdown. Value must be between 0 and 1."); PluginConfig.UserAutoVoteOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "UserAutoVoteOnDeath", false, "Should players auto vote tp when they die."); PluginConfig.VoteAfterTPEvent = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "VoteAfterTPEvent", true, "Should tp voting also be activated after tp event."); PluginConfig.ShowImportantConfigs = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "ShowImportantConfigs", false, "Shows relevant configs whenever voting instructions are shown."); if (Chainloader.PluginInfos.ContainsKey("com.Ehseezed.TPVotingExpanded")) { AddConfigOptions(); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void AddConfigOptions() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_005a: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.PlayerIsReadyMessages)); ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.IgnoredGameModes)); ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.CustomReadyMessages)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(PluginConfig.MajorityVotesCountdownTime, new IntSliderConfig { min = 0, max = 100 })); ModSettingsManager.AddOption((BaseOption)new SliderOption(PluginConfig.PercentageOfTotal, new SliderConfig { min = 0f, max = 100f })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.UserAutoVoteOnDeath)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.VoteAfterTPEvent)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.ShowImportantConfigs)); } }