Minor fixes and modifications

This commit is contained in:
Noikoio 2018-10-31 13:11:12 -07:00
parent 13e3434c38
commit 19cf4d890f
4 changed files with 54 additions and 57 deletions

View file

@ -7,10 +7,27 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
{ {
class Configuration class Configuration
{ {
/// <summary>
/// Channel name in which voting takes place.
/// </summary>
public string VoteChannel { get; }
/// <summary> /// <summary>
/// Command used to vote for the channel's creation. /// Command used to vote for the channel's creation.
/// </summary> /// </summary>
public string VoteCommand { get; } public string VoteCommand { get; }
/// <summary>
/// Number of votes needed to create the channel.
/// </summary>
public int VotePassThreshold { get; }
/// <summary>
/// Amount of time that a voting session can last starting from its initial vote.
/// </summary>
public TimeSpan VotingDuration { get; }
/// <summary>
/// Amount of time to wait before another vote may be initiated, either after a failed vote
/// or from expiration of the temporary channel.
/// </summary>
public TimeSpan VotingCooldown { get; }
/// <summary> /// <summary>
/// Name of the temporary channel, without prefix. /// Name of the temporary channel, without prefix.
@ -22,27 +39,6 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
/// </summary> /// </summary>
public TimeSpan ChannelDuration { get; } public TimeSpan ChannelDuration { get; }
/// <summary>
/// Number of votes needed to create the channel.
/// </summary>
public int VotePassThreshold { get; }
/// <summary>
/// Amount of time that a voting session can last starting from its initial vote.
/// </summary>
public TimeSpan VotingDuration { get; }
/// <summary>
/// Amount of time to wait before another vote may be initiated, either after a failed vote
/// or from expiration of the temporary channel.
/// </summary>
public TimeSpan VotingCooldown { get; }
/// <summary>
/// Channel name in which voting takes place.
/// </summary>
public string VotingChannel { get; }
public Configuration(JObject j) public Configuration(JObject j)
{ {
VoteCommand = j["VoteCommand"]?.Value<string>(); VoteCommand = j["VoteCommand"]?.Value<string>();
@ -52,7 +48,7 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
throw new RuleImportException("'VoteCommand' must not contain spaces."); throw new RuleImportException("'VoteCommand' must not contain spaces.");
TempChannelName = ParseChannelNameConfig(j, "TempChannelName"); TempChannelName = ParseChannelNameConfig(j, "TempChannelName");
VotingChannel = ParseChannelNameConfig(j, "VotingChannel"); VoteChannel = ParseChannelNameConfig(j, "VoteChannel");
var vptProp = j["VotePassThreshold"]; var vptProp = j["VotePassThreshold"];
if (vptProp == null) if (vptProp == null)
@ -70,10 +66,10 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
private string ParseChannelNameConfig(JObject conf, string valueName) private string ParseChannelNameConfig(JObject conf, string valueName)
{ {
var value = j[valueName]?.Value<string>(); var value = conf[valueName]?.Value<string>();
if (string.IsNullOrWhiteSpace(value)) if (string.IsNullOrWhiteSpace(value))
throw new RuleImportException($"'{valueName}' must be specified."); throw new RuleImportException($"'{valueName}' must be specified.");
if (!Regex.IsMatch(TempChannelName, @"^([A-Za-z0-9]|[-_ ])+$")) if (!Regex.IsMatch(value, @"^([A-Za-z0-9]|[-_ ])+$"))
throw new RuleImportException($"'{valueName}' contains one or more invalid characters."); throw new RuleImportException($"'{valueName}' contains one or more invalid characters.");
return value; return value;
} }

View file

@ -25,7 +25,7 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
TempChannelLastActivity = DateTimeOffset.UtcNow; TempChannelLastActivity = DateTimeOffset.UtcNow;
Config = new Configuration(conf); Config = new Configuration(conf);
Voting = new VotingSession(); Voting = new VotingSession(Config);
} }
public SocketTextChannel GetTemporaryChannel(SocketGuild guild) public SocketTextChannel GetTemporaryChannel(SocketGuild guild)

View file

@ -1,5 +1,4 @@
using Discord; using Discord.Rest;
using Discord.Rest;
using Discord.WebSocket; using Discord.WebSocket;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Noikoio.RegexBot.ConfigItem; using Noikoio.RegexBot.ConfigItem;
@ -46,35 +45,35 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
if (arg.Author.IsBot) return; if (arg.Author.IsBot) return;
var guild = (arg.Channel as SocketTextChannel)?.Guild; var guild = (arg.Channel as SocketTextChannel)?.Guild;
if (guild == null) return; if (guild == null) return;
var conf = GetState<GuildInformation>(guild.Id); var info = GetState<GuildInformation>(guild.Id);
if (conf == null) return; if (info == null) return;
// Only check the designated voting channel // Only check the designated voting channel
if (!string.Equals(arg.Channel.Name, conf.Config.VotingChannel, if (!string.Equals(arg.Channel.Name, info.Config.VoteChannel,
StringComparison.InvariantCultureIgnoreCase)) return; StringComparison.InvariantCultureIgnoreCase)) return;
// Check if command invoked // Check if command invoked
if (!arg.Content.StartsWith(conf.Config.VoteCommand, StringComparison.InvariantCultureIgnoreCase)) return; 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; background task may be using this.
bool cooldown; bool cooldown;
bool voteCounted = false; bool voteCounted = false;
string newChannelName = null; string newChannelName = null;
lock (conf) lock (info)
{ {
if (conf.GetTemporaryChannel(guild) != null) return; // channel exists, nothing to vote for if (info.GetTemporaryChannel(guild) != null) return; // channel exists, nothing to vote for
cooldown = conf.Voting.IsInCooldown(); cooldown = info.Voting.IsInCooldown();
if (!cooldown) if (!cooldown)
{ {
voteCounted = conf.Voting.AddVote(arg.Author.Id, out var voteCount); voteCounted = info.Voting.AddVote(arg.Author.Id, out var voteCount);
if (voteCount >= conf.Config.VotePassThreshold) if (voteCount >= info.Config.VotePassThreshold)
{ {
newChannelName = conf.Config.TempChannelName; newChannelName = info.Config.TempChannelName;
} }
} }
// Prepare new temporary channel while we're still locking state // Prepare new temporary channel while we're still locking state
if (newChannelName != null) conf.TempChannelLastActivity = DateTime.UtcNow; if (newChannelName != null) info.TempChannelLastActivity = DateTime.UtcNow;
} }
if (cooldown) if (cooldown)
@ -120,15 +119,16 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
if (arg.Author.IsBot) return Task.CompletedTask; if (arg.Author.IsBot) return Task.CompletedTask;
var guild = (arg.Channel as SocketTextChannel)?.Guild; var guild = (arg.Channel as SocketTextChannel)?.Guild;
if (guild == null) return Task.CompletedTask; if (guild == null) return Task.CompletedTask;
var conf = GetState<GuildInformation>(guild.Id); var info = GetState<GuildInformation>(guild.Id);
if (conf == null) return Task.CompletedTask; if (info == null) return Task.CompletedTask;
lock (conf) lock (info)
{ {
var tch = conf.GetTemporaryChannel(guild); var tch = info.GetTemporaryChannel(guild);
if (tch == null) return Task.CompletedTask;
if (arg.Channel.Name == tch.Name) if (arg.Channel.Name == tch.Name)
{ {
conf.TempChannelLastActivity = DateTimeOffset.UtcNow; info.TempChannelLastActivity = DateTimeOffset.UtcNow;
} }
} }
@ -150,11 +150,11 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
{ {
try try
{ {
var conf = GetState<GuildInformation>(g.Id); var info = GetState<GuildInformation>(g.Id);
if (conf == null) continue; if (info == null) continue;
await BackgroundTempChannelExpiryCheck(g, conf); await BackgroundTempChannelExpiryCheck(g, info);
await BackgroundVoteSessionExpiryCheck(g, conf); await BackgroundVoteSessionExpiryCheck(g, info);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -165,28 +165,28 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
} }
} }
private async Task BackgroundTempChannelExpiryCheck(SocketGuild g, GuildInformation conf) private async Task BackgroundTempChannelExpiryCheck(SocketGuild g, GuildInformation info)
{ {
SocketGuildChannel ch = null; SocketGuildChannel ch = null;
lock (conf) lock (info)
{ {
ch = conf.GetTemporaryChannel(g); ch = info.GetTemporaryChannel(g);
if (ch == null) return; // No temporary channel. Nothing to do. if (ch == null) return; // No temporary channel. Nothing to do.
if (!conf.IsTempChannelExpired()) return; if (!info.IsTempChannelExpired()) return;
// If we got this far, the channel's expiring. Start the voting cooldown. // If we got this far, the channel's expiring. Start the voting cooldown.
conf.Voting.StartCooldown(); info.Voting.StartCooldown();
} }
await ch.DeleteAsync(); await ch.DeleteAsync();
} }
private async Task BackgroundVoteSessionExpiryCheck(SocketGuild g, GuildInformation conf) private async Task BackgroundVoteSessionExpiryCheck(SocketGuild g, GuildInformation info)
{ {
bool act; bool act;
string nameTest; string nameTest;
lock (conf) { lock (info) {
act = conf.Voting.IsSessionExpired(); act = info.Voting.IsSessionExpired();
nameTest = conf.Config.VotingChannel; nameTest = info.Config.VoteChannel;
} }
if (!act) return; if (!act) return;

View file

@ -13,8 +13,9 @@ namespace Noikoio.RegexBot.Module.VoteTempChannel
private List<ulong> _votes; private List<ulong> _votes;
public DateTimeOffset? _cooldownStart; public DateTimeOffset? _cooldownStart;
public VotingSession() public VotingSession(Configuration conf)
{ {
_conf = conf;
_cooldownStart = null; _cooldownStart = null;
_votes = new List<ulong>(); _votes = new List<ulong>();
} }