>pollstats added
This commit is contained in:
parent
8a76d20197
commit
812e9656a1
@ -7,6 +7,7 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ namespace NadekoBot.Modules.Games
|
|||||||
[Group]
|
[Group]
|
||||||
public class PollCommands : ModuleBase
|
public class PollCommands : ModuleBase
|
||||||
{
|
{
|
||||||
public static ConcurrentDictionary<IGuild, Poll> ActivePolls = new ConcurrentDictionary<IGuild, Poll>();
|
public static ConcurrentDictionary<ulong, Poll> ActivePolls = new ConcurrentDictionary<ulong, Poll>();
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
@ -31,6 +32,18 @@ namespace NadekoBot.Modules.Games
|
|||||||
public Task PublicPoll([Remainder] string arg = null)
|
public Task PublicPoll([Remainder] string arg = null)
|
||||||
=> InternalStartPoll(arg, isPublic: true);
|
=> InternalStartPoll(arg, isPublic: true);
|
||||||
|
|
||||||
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task PollStats()
|
||||||
|
{
|
||||||
|
Games.Poll poll;
|
||||||
|
if (!ActivePolls.TryGetValue(Context.Guild.Id, out poll))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await Context.Channel.EmbedAsync(poll.GetStats("Current Poll Results"));
|
||||||
|
}
|
||||||
|
|
||||||
private async Task InternalStartPoll(string arg, bool isPublic = false)
|
private async Task InternalStartPoll(string arg, bool isPublic = false)
|
||||||
{
|
{
|
||||||
var channel = (ITextChannel)Context.Channel;
|
var channel = (ITextChannel)Context.Channel;
|
||||||
@ -44,7 +57,7 @@ namespace NadekoBot.Modules.Games
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var poll = new Poll(Context.Message, data[0], data.Skip(1), isPublic: isPublic);
|
var poll = new Poll(Context.Message, data[0], data.Skip(1), isPublic: isPublic);
|
||||||
if (ActivePolls.TryAdd(channel.Guild, poll))
|
if (ActivePolls.TryAdd(channel.Guild.Id, poll))
|
||||||
{
|
{
|
||||||
await poll.StartPoll().ConfigureAwait(false);
|
await poll.StartPoll().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@ -60,7 +73,7 @@ namespace NadekoBot.Modules.Games
|
|||||||
var channel = (ITextChannel)Context.Channel;
|
var channel = (ITextChannel)Context.Channel;
|
||||||
|
|
||||||
Poll poll;
|
Poll poll;
|
||||||
ActivePolls.TryRemove(channel.Guild, out poll);
|
ActivePolls.TryRemove(channel.Guild.Id, out poll);
|
||||||
await poll.StopPoll().ConfigureAwait(false);
|
await poll.StopPoll().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,20 +82,55 @@ namespace NadekoBot.Modules.Games
|
|||||||
{
|
{
|
||||||
private readonly IUserMessage originalMessage;
|
private readonly IUserMessage originalMessage;
|
||||||
private readonly IGuild guild;
|
private readonly IGuild guild;
|
||||||
private readonly string[] answers;
|
private string[] Answers { get; }
|
||||||
private ConcurrentDictionary<ulong, int> participants = new ConcurrentDictionary<ulong, int>();
|
private ConcurrentDictionary<ulong, int> participants = new ConcurrentDictionary<ulong, int>();
|
||||||
private readonly string question;
|
private readonly string question;
|
||||||
private DateTime started;
|
private DateTime started;
|
||||||
private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
|
private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
|
||||||
private readonly bool isPublic;
|
public bool IsPublic { get; }
|
||||||
|
|
||||||
public Poll(IUserMessage umsg, string question, IEnumerable<string> enumerable, bool isPublic = false)
|
public Poll(IUserMessage umsg, string question, IEnumerable<string> enumerable, bool isPublic = false)
|
||||||
{
|
{
|
||||||
this.originalMessage = umsg;
|
this.originalMessage = umsg;
|
||||||
this.guild = ((ITextChannel)umsg.Channel).Guild;
|
this.guild = ((ITextChannel)umsg.Channel).Guild;
|
||||||
this.question = question;
|
this.question = question;
|
||||||
this.answers = enumerable as string[] ?? enumerable.ToArray();
|
this.Answers = enumerable as string[] ?? enumerable.ToArray();
|
||||||
this.isPublic = isPublic;
|
this.IsPublic = isPublic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmbedBuilder GetStats(string title)
|
||||||
|
{
|
||||||
|
var results = participants.GroupBy(kvp => kvp.Value)
|
||||||
|
.ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
|
||||||
|
.OrderByDescending(kvp => kvp.Value)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var eb = new EmbedBuilder().WithTitle(title);
|
||||||
|
|
||||||
|
var sb = new StringBuilder()
|
||||||
|
.AppendLine(Format.Bold(question))
|
||||||
|
.AppendLine();
|
||||||
|
|
||||||
|
var totalVotesCast = 0;
|
||||||
|
if (results.Length == 0)
|
||||||
|
{
|
||||||
|
sb.AppendLine("No votes cast.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < results.Length; i++)
|
||||||
|
{
|
||||||
|
var result = results[i];
|
||||||
|
sb.AppendLine($"`{i + 1}.` {Format.Bold(Answers[result.Key - 1])} with {Format.Bold(result.Value.ToString())} votes.");
|
||||||
|
totalVotesCast += result.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
eb.WithDescription(sb.ToString())
|
||||||
|
.WithFooter(efb => efb.WithText(totalVotesCast + " total votes cast."));
|
||||||
|
|
||||||
|
return eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartPoll()
|
public async Task StartPoll()
|
||||||
@ -91,8 +139,8 @@ namespace NadekoBot.Modules.Games
|
|||||||
NadekoBot.Client.MessageReceived += Vote;
|
NadekoBot.Client.MessageReceived += Vote;
|
||||||
var msgToSend = $"📃**{originalMessage.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;
|
var num = 1;
|
||||||
msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
|
msgToSend = Answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
|
||||||
if (!isPublic)
|
if (!IsPublic)
|
||||||
msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
|
msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
|
||||||
else
|
else
|
||||||
msgToSend += "\n**Send a Message here with the corresponding number of the answer.**";
|
msgToSend += "\n**Send a Message here with the corresponding number of the answer.**";
|
||||||
@ -102,30 +150,7 @@ namespace NadekoBot.Modules.Games
|
|||||||
public async Task StopPoll()
|
public async Task StopPoll()
|
||||||
{
|
{
|
||||||
NadekoBot.Client.MessageReceived -= Vote;
|
NadekoBot.Client.MessageReceived -= Vote;
|
||||||
try
|
await originalMessage.Channel.EmbedAsync(GetStats("POLL CLOSED")).ConfigureAwait(false);
|
||||||
{
|
|
||||||
var results = participants.GroupBy(kvp => kvp.Value)
|
|
||||||
.ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
|
|
||||||
.OrderByDescending(kvp => kvp.Value);
|
|
||||||
|
|
||||||
var totalVotesCast = results.Sum(kvp => kvp.Value);
|
|
||||||
if (totalVotesCast == 0)
|
|
||||||
{
|
|
||||||
await originalMessage.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var closeMessage = $"--------------**POLL CLOSED**--------------\n" +
|
|
||||||
$"📄 , here are the results:\n";
|
|
||||||
closeMessage = results.Aggregate(closeMessage, (current, kvp) => current + $"`{kvp.Key}.` **[{answers[kvp.Key - 1]}]**" +
|
|
||||||
$" has {kvp.Value} votes." +
|
|
||||||
$"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n");
|
|
||||||
|
|
||||||
await originalMessage.Channel.SendConfirmAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error in poll game {ex}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Vote(SocketMessage imsg)
|
private async void Vote(SocketMessage imsg)
|
||||||
@ -141,11 +166,11 @@ namespace NadekoBot.Modules.Games
|
|||||||
int vote;
|
int vote;
|
||||||
if (!int.TryParse(imsg.Content, out vote))
|
if (!int.TryParse(imsg.Content, out vote))
|
||||||
return;
|
return;
|
||||||
if (vote < 1 || vote > answers.Length)
|
if (vote < 1 || vote > Answers.Length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IMessageChannel ch;
|
IMessageChannel ch;
|
||||||
if (isPublic)
|
if (IsPublic)
|
||||||
{
|
{
|
||||||
//if public, channel must be the same the poll started in
|
//if public, channel must be the same the poll started in
|
||||||
if (originalMessage.Channel.Id != imsg.Channel.Id)
|
if (originalMessage.Channel.Id != imsg.Channel.Id)
|
||||||
@ -167,7 +192,7 @@ namespace NadekoBot.Modules.Games
|
|||||||
//user can vote only once
|
//user can vote only once
|
||||||
if (participants.TryAdd(msg.Author.Id, vote))
|
if (participants.TryAdd(msg.Author.Id, vote))
|
||||||
{
|
{
|
||||||
if (!isPublic)
|
if (!IsPublic)
|
||||||
{
|
{
|
||||||
await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
|
await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
27
src/NadekoBot/Resources/CommandStrings.Designer.cs
generated
27
src/NadekoBot/Resources/CommandStrings.Designer.cs
generated
@ -5162,6 +5162,33 @@ namespace NadekoBot.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to pollstats.
|
||||||
|
/// </summary>
|
||||||
|
public static string pollstats_cmd {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("pollstats_cmd", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Shows the poll results without stopping the poll on this server..
|
||||||
|
/// </summary>
|
||||||
|
public static string pollstats_desc {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("pollstats_desc", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to `{0}pollstats`.
|
||||||
|
/// </summary>
|
||||||
|
public static string pollstats_usage {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("pollstats_usage", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to prune clr.
|
/// Looks up a localized string similar to prune clr.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2880,4 +2880,13 @@
|
|||||||
<data name="createinvite_usage" xml:space="preserve">
|
<data name="createinvite_usage" xml:space="preserve">
|
||||||
<value>`{0}crinv`</value>
|
<value>`{0}crinv`</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="pollstats_cmd" xml:space="preserve">
|
||||||
|
<value>pollstats</value>
|
||||||
|
</data>
|
||||||
|
<data name="pollstats_desc" xml:space="preserve">
|
||||||
|
<value>Shows the poll results without stopping the poll on this server.</value>
|
||||||
|
</data>
|
||||||
|
<data name="pollstats_usage" xml:space="preserve">
|
||||||
|
<value>`{0}pollstats`</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
Loading…
Reference in New Issue
Block a user