From 0b6e76f446802172bd713c899f5b67ff62095b35 Mon Sep 17 00:00:00 2001 From: Voltstro Date: Sat, 4 May 2019 23:44:34 +1000 Subject: [PATCH] Added votes You can now do votes. --- Pootis-Bot/Core/Bot.cs | 27 +++- Pootis-Bot/Modules/Misc.cs | 8 +- Pootis-Bot/Services/VoteGivewayService.cs | 149 ++++++++++++++++++++-- 3 files changed, 165 insertions(+), 19 deletions(-) diff --git a/Pootis-Bot/Core/Bot.cs b/Pootis-Bot/Core/Bot.cs index ad300c4f..473e43b9 100644 --- a/Pootis-Bot/Core/Bot.cs +++ b/Pootis-Bot/Core/Bot.cs @@ -5,6 +5,7 @@ using Discord.Commands; using Discord.WebSocket; using Pootis_Bot.Entities; +using Pootis_Bot.Services; namespace Pootis_Bot.Core { @@ -114,7 +115,31 @@ private Task ReactionAdded(Cacheable cache, ISocketMessageC } } else - LevelingSystem.UserSentMessage((SocketGuildUser)reaction.User, (SocketTextChannel)reaction.Channel, 5); + { + if(VoteGivewayService.isVoteRunning) // If there is a vote going on then check to make sure the reaction doesn't have anything to do with that. + { + foreach (var vote in VoteGivewayService.votes) + { + if(reaction.MessageId == vote.VoteMessageID) + { + if(reaction.Emote.Name == vote.YesEmoji) + { + vote.YesCount++; + } + + else if(reaction.Emote.Name == vote.NoEmoji) + { + vote.NoCount++; + } + } + } + } + else + { + if (!((SocketGuildUser)reaction.User).IsBot) + LevelingSystem.UserSentMessage((SocketGuildUser)reaction.User, (SocketTextChannel)reaction.Channel, 5); + } + } return Task.CompletedTask; } diff --git a/Pootis-Bot/Modules/Misc.cs b/Pootis-Bot/Modules/Misc.cs index e1d8f3e5..fdc24eee 100644 --- a/Pootis-Bot/Modules/Misc.cs +++ b/Pootis-Bot/Modules/Misc.cs @@ -14,7 +14,7 @@ public class Misc : ModuleBase // Description - Misc commands // Contributors - Creepysin, - VoteGivewayService voteGivewayService; + private readonly VoteGivewayService voteGivewayService; public Misc() { @@ -77,11 +77,11 @@ public async Task Ping() await Context.Channel.SendMessageAsync($"Pong! {Context.Client.Latency}ms"); } - [Command("vote")] + [Command("vote", RunMode = RunMode.Async)] [Summary("Starts a vote")] - public async Task Vote() + public async Task Vote(string time, string title, string description, string yesEmoji, string noEmoji) { - await voteGivewayService.StartVote(Context.Guild, Context.Channel, "", "", "", "", ""); + await voteGivewayService.StartVote(Context.Guild, Context.Channel, Context.User, time, title, description, yesEmoji, noEmoji); } #region Functions diff --git a/Pootis-Bot/Services/VoteGivewayService.cs b/Pootis-Bot/Services/VoteGivewayService.cs index 63959038..5e22b2c1 100644 --- a/Pootis-Bot/Services/VoteGivewayService.cs +++ b/Pootis-Bot/Services/VoteGivewayService.cs @@ -1,4 +1,8 @@ -using System.Threading.Tasks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Discord; using Discord.WebSocket; using Pootis_Bot.Core; @@ -6,27 +10,144 @@ namespace Pootis_Bot.Services { public class VoteGivewayService { - enum TimeType { Hour, Days, Seconds } + private enum TimeType { Days, Hours, Secs} + public static List votes = new List(); + public static bool isVoteRunning; - public async Task StartVote(SocketGuild guild, ISocketMessageChannel channel, string time, string title, string description, string yesEmoji, string noEmoji) + public async Task StartVote(SocketGuild guild, ISocketMessageChannel channel, SocketUser user, string time, string title, string description, string yesEmoji, string noEmoji) { - TimeType timeType; - - if (time.EndsWith("h") || time.EndsWith("hrs") || time.EndsWith("hours")) - timeType = TimeType.Hour; - else if (time.EndsWith("s") || time.EndsWith("sec") || time.EndsWith("secs") || time.EndsWith("seconds")) - timeType = TimeType.Seconds; - else if (time.EndsWith("d") || time.EndsWith("days")) - timeType = TimeType.Days; - else + string[] times = time.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + int totalTime = 0; + + foreach(var _time in times) { - await channel.SendMessageAsync("Invaild time format, the time must end with either `h` for hours, `s` for seconds and `d` for days!"); + TimeType timeType; + + string formated; + double currentTime = 0; + + //Remove either h, hrs, hours, s, sec, secs, seconds, d, days depending on the time format + if (_time.EndsWith("h") || time.EndsWith("hrs") || time.EndsWith("hours")) + { + formated = _time.Replace("h", "").Replace("hrs", "").Replace("hours", ""); + timeType = TimeType.Hours; + } + else if (_time.EndsWith("s") || time.EndsWith("sec") || time.EndsWith("secs") || time.EndsWith("seconds")) + { + formated = _time.Replace("s", "").Replace("sec", "").Replace("secs", "").Replace("seconds", ""); + timeType = TimeType.Secs; + } + else if (_time.EndsWith("d") || time.EndsWith("days")) + { + formated = _time.Replace("d", "").Replace("days", ""); + timeType = TimeType.Days; + } + else //It didn't include a support 'format' i geuss u would call it? + { + await channel.SendMessageAsync("Invaild time format, the time must end with either `h` for hours, `s` for seconds and `d` for days!"); + return; + } + + if (!int.TryParse(formated, out int temp)) //Convert the formated string to a int + { + await channel.SendMessageAsync("The time foramt is incorrect! Make sure it is something like this: `1h`."); + return; + } + + //Convert the time depending on what TimeType it is. + if (timeType == TimeType.Days) + { + TimeSpan tp = TimeSpan.FromDays(temp); + currentTime = tp.TotalMilliseconds; + } + else if(timeType == TimeType.Hours) + { + TimeSpan tp = TimeSpan.FromHours(temp); + currentTime = tp.TotalMilliseconds; + } + else + { + TimeSpan tp = TimeSpan.FromSeconds(temp); + currentTime = tp.TotalMilliseconds; + } + + totalTime += (int) currentTime; + } + + //Setup emojis + if(!Global.ContainsUnicodeCharacter(yesEmoji) || !Global.ContainsUnicodeCharacter(noEmoji)) + { + await channel.SendMessageAsync("Your emoji(s) are not unicode! Use https://unicode.org/emoji/charts/full-emoji-list.html to select an emoji."); return; } - Global.WriteMessage("The server {} has started vote that lasting {} seconds"); + var yesEmote = new Emoji(yesEmoji); + var noEmote = new Emoji(noEmoji); + + EmbedBuilder embed = new EmbedBuilder(); + embed.WithTitle("**Vote**: " + title); + embed.WithDescription(description + $"\n\nReact with {yesEmoji} to say **YES** or {noEmoji} to say **NO**."); + embed.WithFooter($"Vote started by {user.Username} @ ", user.GetAvatarUrl()); + embed.WithCurrentTimestamp(); + + var message = await channel.SendMessageAsync("", false, embed.Build()); + + // Add yes and no reactions + await message.AddReactionAsync(yesEmote); + await message.AddReactionAsync(noEmote); + + isVoteRunning = true; + var vote = new Vote + { + VoteMessageID = message.Id, + YesEmoji = yesEmoji, + NoEmoji = noEmoji + }; + + votes.Add(vote); + Global.WriteMessage($"A vote has started on the guild {guild.Name}({guild.Id})", ConsoleColor.Green); + + await Task.Delay(totalTime); // Wait for the vote to finish + + EmbedBuilder finishedVote = new EmbedBuilder(); + finishedVote.WithTitle("**Vote Results**: " + title); + finishedVote.WithDescription($"The vote has finished! Here are the results: \n**Yes**: {vote.YesCount}\n**No**: {vote.NoCount}"); + finishedVote.WithFooter($"Vote was started by {user.Username} at ", user.GetAvatarUrl()); + finishedVote.WithCurrentTimestamp(); + + await channel.SendMessageAsync("", false, finishedVote.Build()); + + votes.Remove(vote); + + Global.WriteMessage($"The vote on {guild.Name}({guild.Id}) has finished.", ConsoleColor.Green); + + //Check to make sure no other votes are running. + if (votes.Count == 0) + isVoteRunning = false; } + + public static Vote GetVote(ulong id) + { + var result = from a in votes + where a.VoteMessageID == id + select a; + + var server = result.FirstOrDefault(); + return server; + } + + public class Vote + { + public ulong VoteMessageID { get; set; } + + public string YesEmoji { get; set; } + public string NoEmoji { get; set; } + + public int YesCount { get; set; } + public int NoCount { get; set; } + } + } }