diff --git a/ConfigItem/EntityList.cs b/ConfigItem/EntityList.cs index 2a3893b..9e87b56 100644 --- a/ConfigItem/EntityList.cs +++ b/ConfigItem/EntityList.cs @@ -123,5 +123,13 @@ namespace Noikoio.RegexBot.ConfigItem // No match. return false; } + + /// + /// Determines if this is an empty list. + /// + public bool IsEmpty() + { + return Channels.Count() + Roles.Count() + Users.Count() == 0; + } } } diff --git a/Module/VoteTempChannel/Configuration.cs b/Module/VoteTempChannel/Configuration.cs index 4bb4ce2..cd7916f 100644 --- a/Module/VoteTempChannel/Configuration.cs +++ b/Module/VoteTempChannel/Configuration.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json.Linq; using Noikoio.RegexBot.ConfigItem; using System; +using System.Linq; using System.Text.RegularExpressions; namespace Noikoio.RegexBot.Module.VoteTempChannel @@ -39,6 +40,12 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel /// public TimeSpan ChannelDuration { get; } + /// + /// Entities that are allowed to cast the initial vote. + /// An empty list allows anyone to initiate a vote. + /// + public EntityList VoteStarters { get; } + public Configuration(JObject j) { VoteCommand = j["VoteCommand"]?.Value(); @@ -62,6 +69,9 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel ChannelDuration = ParseTimeConfig(j, "ChannelDuration"); VotingDuration = ParseTimeConfig(j, "VotingDuration"); VotingCooldown = ParseTimeConfig(j, "VotingCooldown"); + + VoteStarters = new EntityList(j["VoteStarters"]); + // Accepts empty lists. } private string ParseChannelNameConfig(JObject conf, string valueName) diff --git a/Module/VoteTempChannel/VoteTempChannel.cs b/Module/VoteTempChannel/VoteTempChannel.cs index f17d593..356561a 100644 --- a/Module/VoteTempChannel/VoteTempChannel.cs +++ b/Module/VoteTempChannel/VoteTempChannel.cs @@ -55,13 +55,21 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel // Check if command invoked if (!arg.Content.StartsWith(info.Config.VoteCommand, StringComparison.InvariantCultureIgnoreCase)) return; - // Check if we're accepting votes. Locking here; background task may be using this. + // Check if we're accepting votes. Locking here; other tasks may alter this data. bool cooldown; bool voteCounted = false; string newChannelName = null; lock (info) { - if (info.GetTemporaryChannel(guild) != null) return; // channel exists, nothing to vote for + if (info.GetTemporaryChannel(guild) != null) return; // channel exists, do nothing + + if (info.Voting.AwaitingInitialVote()) + { + // Vote not in effect. Ignore those not allowed to initiate a vote (if configured). + if (!info.Config.VoteStarters.IsEmpty() && + !info.Config.VoteStarters.ExistsInList(arg)) return; + } + cooldown = info.Voting.IsInCooldown(); if (!cooldown) { @@ -72,7 +80,7 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel } } - // Prepare new temporary channel while we're still locking state + // Prepare new temporary channel while we're still locking if (newChannelName != null) info.TempChannelLastActivity = DateTime.UtcNow; } @@ -105,7 +113,6 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel + "\nBe aware that this channel is temporary and **will** be deleted later."); newChannelName = newCh.Id.ToString(); // For use in the confirmation message } - await arg.Channel.SendMessageAsync(":white_check_mark: Channel creation vote has been counted." + (newChannelName != null ? $"\n<#{newChannelName}> has been created!" : "")); } diff --git a/Module/VoteTempChannel/VotingSession.cs b/Module/VoteTempChannel/VotingSession.cs index e488243..45c5a35 100644 --- a/Module/VoteTempChannel/VotingSession.cs +++ b/Module/VoteTempChannel/VotingSession.cs @@ -38,6 +38,15 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel return true; } + /// + /// Reports if this session is awaiting its first vote. + /// + public bool AwaitingInitialVote() + { + if (IsInCooldown()) return false; + return _votes.Count == 0; + } + /// /// Checks if the voting session has expired. /// To be called by the background task. This automatically resets and sets cooldown.