From a1056c91947642c027ba3356410164b6c00d165f Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 24 Oct 2016 17:34:30 +0200 Subject: [PATCH 1/4] >poll fixed --- .../Modules/Games/Commands/PollCommands.cs | 36 +++++++++---------- .../Searches/Commands/PlaceCommands.cs | 5 --- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs index c31fc654..ce56f3b1 100644 --- a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs @@ -1,5 +1,6 @@ ο»Ώusing Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using System; using System.Collections.Concurrent; @@ -52,8 +53,9 @@ namespace NadekoBot.Modules.Games public class Poll { private readonly IUserMessage umsg; + private readonly IGuild guild; private readonly string[] answers; - private ConcurrentDictionary participants = new ConcurrentDictionary(); + private ConcurrentDictionary participants = new ConcurrentDictionary(); private readonly string question; private DateTime started; private CancellationTokenSource pollCancellationSource = new CancellationTokenSource(); @@ -61,6 +63,7 @@ namespace NadekoBot.Modules.Games public Poll(IUserMessage umsg, string question, IEnumerable enumerable) { this.umsg = umsg; + this.guild = ((ITextChannel)umsg.Channel).Guild; this.question = question; this.answers = enumerable as string[] ?? enumerable.ToArray(); } @@ -69,9 +72,7 @@ namespace NadekoBot.Modules.Games { started = DateTime.Now; NadekoBot.Client.MessageReceived += Vote; - var msgToSend = $@"πŸ“ƒ**{umsg.Author.Username}** has created a poll which requires your attention: - -**{question}**\n"; + var msgToSend = $"πŸ“ƒ**{umsg.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n"; var num = 1; msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n"); msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; @@ -107,31 +108,30 @@ namespace NadekoBot.Modules.Games } } - private Task Vote(IMessage imsg) + private async Task Vote(IMessage imsg) { // has to be a user message var msg = imsg as IUserMessage; if (msg == null || msg.Author.IsBot) - return Task.CompletedTask; + return; // channel must be private IPrivateChannel ch; if ((ch = msg.Channel as IPrivateChannel) == null) - return Task.CompletedTask; + return; + var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false); + if (!guildUsers.Any(u => u.Id == imsg.Author.Id)) + return; // has to be an integer int vote; - if (!int.TryParse(msg.Content, out vote)) return Task.CompletedTask; - - var t = Task.Run(async () => + if (!int.TryParse(msg.Content, out vote)) return; + if (vote < 1 || vote > answers.Length) + return; + if (participants.TryAdd(msg.Author.Id, vote)) { - if (vote < 1 || vote > answers.Length) - return; - if (participants.TryAdd(msg.Author, vote)) - { - try { await ((IMessageChannel)ch).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); } catch { } - } - }); - return Task.CompletedTask; + try { await ((IMessageChannel)ch).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); } catch { } + } + return; } } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs b/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs index 61997efc..40df37e3 100644 --- a/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs @@ -87,11 +87,6 @@ namespace NadekoBot.Modules.Searches url += $"/{width}/{height}"; - //using (var http = new HttpClient()) - //{ - // var res = await http.GetStreamAsync(url).ConfigureAwait(false); - // await channel.SendFileAsync() - //} await channel.SendMessageAsync(url).ConfigureAwait(false); } } From 4fa0f1533ab6ee616fa58b4bc3872e29de27dd69 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 24 Oct 2016 17:36:06 +0200 Subject: [PATCH 2/4] don't dm owner if integer is sent to the bot, and don't send message string, this is to prevent bot replying to poll vote --- src/NadekoBot/Services/CommandHandler.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index df6fc384..a70eabe4 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -173,6 +173,10 @@ namespace NadekoBot.Services { if (msg.Channel is IPrivateChannel) { + //rofl, gotta do this to prevent this message from occuring on polls + int vote; + if (int.TryParse(msg.Content, out vote)) return; + await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false); await DMForwardCommands.HandleDMForwarding(msg, ownerChannels); From 94bbc369732a20a8fef08ace0850a1de6dd46465 Mon Sep 17 00:00:00 2001 From: Jordan Fearnley Date: Mon, 24 Oct 2016 18:13:23 +0100 Subject: [PATCH 3/4] :tada: :sparkles: A wild new license has appeared! --- license.md | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/license.md b/license.md index ad9c4e5f..68a49daa 100644 --- a/license.md +++ b/license.md @@ -1,19 +1,24 @@ -Copyright (c) 2015 Master Kwoth +This is free and unencumbered software released into the public domain. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to From 443c6297d9c7107a6469a46c6a9661564669dedf Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 24 Oct 2016 20:26:28 +0200 Subject: [PATCH 4/4] Public poll added. Fixed normal poll bugs. #264 --- .../Modules/Games/Commands/PollCommands.cs | 108 +++++++++++++----- .../Resources/CommandStrings.Designer.cs | 29 ++++- src/NadekoBot/Resources/CommandStrings.resx | 11 +- 3 files changed, 116 insertions(+), 32 deletions(-) diff --git a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs index ce56f3b1..48cfde10 100644 --- a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs @@ -16,8 +16,18 @@ namespace NadekoBot.Modules.Games public static ConcurrentDictionary ActivePolls = new ConcurrentDictionary(); [NadekoCommand, Usage, Description, Aliases] + [RequirePermission(GuildPermission.ManageMessages)] [RequireContext(ContextType.Guild)] - public async Task Poll(IUserMessage umsg, [Remainder] string arg = null) + public Task Poll(IUserMessage umsg, [Remainder] string arg = null) + => InternalStartPoll(umsg, arg, isPublic: false); + + [NadekoCommand, Usage, Description, Aliases] + [RequirePermission(GuildPermission.ManageMessages)] + [RequireContext(ContextType.Guild)] + public Task PublicPoll(IUserMessage umsg, [Remainder] string arg = null) + => InternalStartPoll(umsg, arg, isPublic: true); + + private async Task InternalStartPoll(IUserMessage umsg, string arg, bool isPublic = false) { var channel = (ITextChannel)umsg.Channel; @@ -29,57 +39,63 @@ namespace NadekoBot.Modules.Games if (data.Length < 3) return; - var poll = new Poll(umsg, data[0], data.Skip(1)); + var poll = new Poll(umsg, data[0], data.Skip(1), isPublic: isPublic); if (ActivePolls.TryAdd(channel.Guild, poll)) { await poll.StartPoll().ConfigureAwait(false); } + else + await channel.SendMessageAsync("`Poll is already running on this server.`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] + [RequirePermission(GuildPermission.ManageMessages)] [RequireContext(ContextType.Guild)] public async Task Pollend(IUserMessage umsg) { var channel = (ITextChannel)umsg.Channel; - if (!(umsg.Author as IGuildUser).GuildPermissions.ManageChannels) - return; Poll poll; - ActivePolls.TryGetValue(channel.Guild, out poll); - await poll.StopPoll(channel).ConfigureAwait(false); + ActivePolls.TryRemove(channel.Guild, out poll); + await poll.StopPoll().ConfigureAwait(false); } } public class Poll { - private readonly IUserMessage umsg; + private readonly IUserMessage originalMessage; private readonly IGuild guild; private readonly string[] answers; private ConcurrentDictionary participants = new ConcurrentDictionary(); private readonly string question; private DateTime started; private CancellationTokenSource pollCancellationSource = new CancellationTokenSource(); + private readonly bool isPublic; - public Poll(IUserMessage umsg, string question, IEnumerable enumerable) + public Poll(IUserMessage umsg, string question, IEnumerable enumerable, bool isPublic = false) { - this.umsg = umsg; + this.originalMessage = umsg; this.guild = ((ITextChannel)umsg.Channel).Guild; this.question = question; this.answers = enumerable as string[] ?? enumerable.ToArray(); + this.isPublic = isPublic; } public async Task StartPoll() { started = DateTime.Now; NadekoBot.Client.MessageReceived += Vote; - var msgToSend = $"πŸ“ƒ**{umsg.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n"; + var msgToSend = $"πŸ“ƒ**{originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n"; var num = 1; msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n"); - msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; - await umsg.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false); + if (!isPublic) + msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; + else + msgToSend += "\n**Send a Message here with the corresponding number of the answer.**"; + await originalMessage.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false); } - public async Task StopPoll(IGuildChannel ch) + public async Task StopPoll() { NadekoBot.Client.MessageReceived -= Vote; try @@ -91,7 +107,7 @@ namespace NadekoBot.Modules.Games var totalVotesCast = results.Sum(kvp => kvp.Value); if (totalVotesCast == 0) { - await umsg.Channel.SendMessageAsync("πŸ“„ **No votes have been cast.**").ConfigureAwait(false); + await originalMessage.Channel.SendMessageAsync("πŸ“„ **No votes have been cast.**").ConfigureAwait(false); return; } var closeMessage = $"--------------**POLL CLOSED**--------------\n" + @@ -100,7 +116,7 @@ namespace NadekoBot.Modules.Games $" has {kvp.Value} votes." + $"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n"); - await umsg.Channel.SendMessageAsync($"πŸ“„ **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); + await originalMessage.Channel.SendMessageAsync($"πŸ“„ **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); } catch (Exception ex) { @@ -108,30 +124,62 @@ namespace NadekoBot.Modules.Games } } - private async Task Vote(IMessage imsg) + private Task Vote(IMessage imsg) { // has to be a user message var msg = imsg as IUserMessage; if (msg == null || msg.Author.IsBot) - return; - // channel must be private - IPrivateChannel ch; - if ((ch = msg.Channel as IPrivateChannel) == null) - return; - var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false); - if (!guildUsers.Any(u => u.Id == imsg.Author.Id)) - return; + return Task.CompletedTask; // has to be an integer int vote; - if (!int.TryParse(msg.Content, out vote)) return; + if (!int.TryParse(imsg.Content, out vote)) + return Task.CompletedTask; if (vote < 1 || vote > answers.Length) - return; - if (participants.TryAdd(msg.Author.Id, vote)) + return Task.CompletedTask; + + var t = Task.Run(async () => { - try { await ((IMessageChannel)ch).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); } catch { } - } - return; + try + { + IMessageChannel ch; + if (isPublic) + { + //if public, channel must be the same the poll started in + if (originalMessage.Channel.Id != imsg.Channel.Id) + return; + ch = imsg.Channel; + } + else + { + //if private, channel must be dm channel + if ((ch = msg.Channel as IDMChannel) == null) + return; + + // user must be a member of the guild this poll is in + var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false); + if (!guildUsers.Any(u => u.Id == imsg.Author.Id)) + return; + } + + //user can vote only once + if (participants.TryAdd(msg.Author.Id, vote)) + { + if (!isPublic) + { + await ch.SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); + } + else + { + var toDelete = await ch.SendMessageAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false); + await Task.Delay(5000); + await toDelete.DeleteAsync().ConfigureAwait(false); + } + } + } + catch { } + }); + return Task.CompletedTask; } } } \ No newline at end of file diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index b3153042..8a728890 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -4443,7 +4443,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Creates a poll, only person who has manage server permission can do it.. + /// Looks up a localized string similar to Creates a poll which requires users to send the number of the voting option to the bot.. /// public static string poll_desc { get { @@ -4514,6 +4514,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to publicpoll ppoll. + /// + public static string publicpoll_cmd { + get { + return ResourceManager.GetString("publicpoll_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creates a public poll which requires users to type a number of the voting option in the channel command is ran in.. + /// + public static string publicpoll_desc { + get { + return ResourceManager.GetString("publicpoll_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}ppoll Question?;Answer1;Answ 2;A_3`. + /// + public static string publicpoll_usage { + get { + return ResourceManager.GetString("publicpoll_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to queue q yq. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 9ad7965d..36b807dc 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -1336,7 +1336,7 @@ poll - Creates a poll, only person who has manage server permission can do it. + Creates a poll which requires users to send the number of the voting option to the bot. `{0}poll Question?;Answer1;Answ 2;A_3` @@ -2538,4 +2538,13 @@ `{0}totube` + + publicpoll ppoll + + + Creates a public poll which requires users to type a number of the voting option in the channel command is ran in. + + + `{0}ppoll Question?;Answer1;Answ 2;A_3` + \ No newline at end of file