Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TPVotingExpanded v0.1.1
TPVoting.dll
Decompiled 8 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)); } }