geekbot/Geekbot.net/Commands/Rank.cs

145 lines
5.7 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
2018-01-15 20:01:13 +01:00
using Discord.WebSocket;
using Geekbot.net.Lib;
using Serilog;
using StackExchange.Redis;
namespace Geekbot.net.Commands
{
public class Rank : ModuleBase
{
2017-12-29 01:53:50 +01:00
private readonly IEmojiConverter _emojiConverter;
private readonly IErrorHandler _errorHandler;
private readonly IGeekbotLogger _logger;
2017-12-29 01:53:50 +01:00
private readonly IDatabase _redis;
private readonly IUserRepository _userRepository;
2018-01-15 20:01:13 +01:00
private readonly DiscordSocketClient _client;
2017-12-29 01:53:50 +01:00
public Rank(IDatabase redis, IErrorHandler errorHandler, IGeekbotLogger logger, IUserRepository userRepository,
2018-01-15 20:01:13 +01:00
IEmojiConverter emojiConverter, DiscordSocketClient client)
{
_redis = redis;
_errorHandler = errorHandler;
_logger = logger;
_userRepository = userRepository;
2017-11-06 23:55:28 +01:00
_emojiConverter = emojiConverter;
2018-01-15 20:01:13 +01:00
_client = client;
}
2017-12-29 01:53:50 +01:00
[Command("rank", RunMode = RunMode.Async)]
2017-10-12 16:34:10 +02:00
[Remarks(CommandCategories.Statistics)]
[Summary("get user top 10 in messages or karma")]
2017-12-29 01:53:50 +01:00
public async Task RankCmd([Summary("type")] string typeUnformated = "messages",
[Summary("amount")] int amount = 10)
{
try
{
var type = typeUnformated.ToCharArray().First().ToString().ToUpper() + typeUnformated.Substring(1);
2017-12-29 01:03:38 +01:00
if (!type.Equals("Messages") && !type.Equals("Karma") && !type.Equals("Rolls"))
{
2017-12-29 01:03:38 +01:00
await ReplyAsync("Valid types are '`messages`' '`karma`', '`rolls`'");
return;
}
2017-12-29 01:53:50 +01:00
var replyBuilder = new StringBuilder();
if (amount > 20)
{
replyBuilder.AppendLine(":warning: Limiting to 20");
amount = 20;
}
2017-12-29 01:53:50 +01:00
var messageList = _redis.HashGetAll($"{Context.Guild.Id}:{type}");
var sortedList = messageList.OrderByDescending(e => e.Value).ToList();
var guildMessages = (int) sortedList.First().Value;
2018-01-15 20:01:13 +01:00
sortedList.Remove(sortedList.Single(e => e.Name.ToString().Equals(_client.CurrentUser.Id.ToString())));
2017-12-28 22:58:29 +01:00
if (type == "Messages") sortedList.RemoveAt(0);
var highscoreUsers = new Dictionary<RankUserPolyfill, int>();
var listLimiter = 1;
var failedToRetrieveUser = false;
foreach (var user in sortedList)
{
if (listLimiter > amount) break;
try
{
2017-12-29 01:53:50 +01:00
var guildUser = _userRepository.Get((ulong) user.Name);
if (guildUser.Username != null)
{
2017-12-29 01:53:50 +01:00
highscoreUsers.Add(new RankUserPolyfill
{
Username = guildUser.Username,
Discriminator = guildUser.Discriminator
}, (int) user.Value);
}
else
{
2017-12-29 01:53:50 +01:00
highscoreUsers.Add(new RankUserPolyfill
{
Id = user.Name
}, (int) user.Value);
failedToRetrieveUser = true;
}
2017-12-29 01:53:50 +01:00
listLimiter++;
}
catch (Exception e)
{
_logger.Warning("Geekbot", $"Could not retrieve user {user.Name}", e);
}
}
2017-12-29 01:53:50 +01:00
if (failedToRetrieveUser) replyBuilder.AppendLine(":warning: Couldn't get all userdata\n");
replyBuilder.AppendLine($":bar_chart: **{type} Highscore for {Context.Guild.Name}**");
var highscorePlace = 1;
foreach (var user in highscoreUsers)
{
replyBuilder.Append(highscorePlace < 11
? $"{_emojiConverter.numberToEmoji(highscorePlace)} "
: $"`{highscorePlace}.` ");
replyBuilder.Append(user.Key.Username != null
? $"**{user.Key.Username}#{user.Key.Discriminator}**"
: $"**{user.Key.Id}**");
switch (type)
{
case "Messages":
var percent = Math.Round((double) (100 * user.Value) / guildMessages, 2);
replyBuilder.Append($" - {percent}% of total - {user.Value} messages");
break;
case "Karma":
replyBuilder.Append($" - {user.Value} Karma");
break;
2017-12-29 01:03:38 +01:00
case "Rolls":
replyBuilder.Append($" - {user.Value} Guessed");
2017-12-29 01:53:50 +01:00
break;
}
replyBuilder.Append("\n");
2017-12-29 01:53:50 +01:00
highscorePlace++;
}
2017-12-29 01:53:50 +01:00
await ReplyAsync(replyBuilder.ToString());
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
}
}
}
2017-12-29 01:53:50 +01:00
internal class RankUserPolyfill
{
public string Username { get; set; }
public string Discriminator { get; set; }
public string Id { get; set; }
}
2017-04-12 21:49:04 +02:00
}