2017-10-03 00:22:26 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Discord.Commands;
|
2018-05-10 17:56:43 +02:00
|
|
|
|
using Geekbot.net.Database;
|
2018-05-26 02:33:45 +02:00
|
|
|
|
using Geekbot.net.Lib.AlmostRedis;
|
2018-05-03 00:56:06 +02:00
|
|
|
|
using Geekbot.net.Lib.Converters;
|
|
|
|
|
using Geekbot.net.Lib.ErrorHandling;
|
2018-05-10 17:56:43 +02:00
|
|
|
|
using Geekbot.net.Lib.Extensions;
|
2018-05-03 00:56:06 +02:00
|
|
|
|
using Geekbot.net.Lib.UserRepository;
|
2018-05-13 21:06:41 +02:00
|
|
|
|
using StackExchange.Redis;
|
2017-10-03 00:22:26 +02:00
|
|
|
|
|
2018-05-03 21:20:49 +02:00
|
|
|
|
namespace Geekbot.net.Commands.User.Ranking
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
|
|
|
|
public class Rank : ModuleBase
|
|
|
|
|
{
|
2017-12-29 01:53:50 +01:00
|
|
|
|
private readonly IEmojiConverter _emojiConverter;
|
2017-10-03 00:22:26 +02:00
|
|
|
|
private readonly IErrorHandler _errorHandler;
|
2018-05-10 17:56:43 +02:00
|
|
|
|
private readonly DatabaseContext _database;
|
2017-10-03 00:22:26 +02:00
|
|
|
|
private readonly IUserRepository _userRepository;
|
2018-05-26 02:33:45 +02:00
|
|
|
|
private readonly IAlmostRedis _redis;
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2018-05-13 21:33:48 +02:00
|
|
|
|
public Rank(DatabaseContext database, IErrorHandler errorHandler, IUserRepository userRepository,
|
2018-05-26 02:33:45 +02:00
|
|
|
|
IEmojiConverter emojiConverter, IAlmostRedis redis)
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
_database = database;
|
2017-10-03 00:22:26 +02:00
|
|
|
|
_errorHandler = errorHandler;
|
|
|
|
|
_userRepository = userRepository;
|
2017-11-06 23:55:28 +01:00
|
|
|
|
_emojiConverter = emojiConverter;
|
2018-05-13 21:06:41 +02:00
|
|
|
|
_redis = redis;
|
2017-10-03 00:22:26 +02:00
|
|
|
|
}
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2017-10-03 00:22:26 +02:00
|
|
|
|
[Command("rank", RunMode = RunMode.Async)]
|
2017-12-28 22:38:49 +01:00
|
|
|
|
[Summary("get user top 10 in messages or karma")]
|
2018-05-03 21:20:49 +02:00
|
|
|
|
public async Task RankCmd([Summary("type")] string typeUnformated = "messages", [Summary("amount")] int amount = 10)
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
RankType type;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
type = Enum.Parse<RankType>(typeUnformated.ToLower());
|
|
|
|
|
}
|
|
|
|
|
catch
|
2017-12-28 22:38:49 +01:00
|
|
|
|
{
|
2017-12-29 01:03:38 +01:00
|
|
|
|
await ReplyAsync("Valid types are '`messages`' '`karma`', '`rolls`'");
|
2017-12-28 22:38:49 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2018-05-10 17:56:43 +02:00
|
|
|
|
|
2017-12-28 22:38:49 +01:00
|
|
|
|
var replyBuilder = new StringBuilder();
|
|
|
|
|
if (amount > 20)
|
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
replyBuilder.AppendLine(":warning: Limiting to 20\n");
|
2017-12-28 22:38:49 +01:00
|
|
|
|
amount = 20;
|
|
|
|
|
}
|
2018-05-10 17:56:43 +02:00
|
|
|
|
|
|
|
|
|
Dictionary<ulong, int> list;
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2018-05-10 17:56:43 +02:00
|
|
|
|
switch (type)
|
2018-02-15 00:07:11 +01:00
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
case RankType.messages:
|
|
|
|
|
list = GetMessageList(amount);
|
|
|
|
|
break;
|
|
|
|
|
case RankType.karma:
|
|
|
|
|
list = GetKarmaList(amount);
|
|
|
|
|
break;
|
|
|
|
|
case RankType.rolls:
|
|
|
|
|
list = GetRollsList(amount);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-05-13 21:06:41 +02:00
|
|
|
|
await ReplyAsync("Valid types are '`messages`' '`karma`', '`rolls`'");
|
|
|
|
|
return;
|
2018-02-15 00:07:11 +01:00
|
|
|
|
}
|
2018-05-10 17:56:43 +02:00
|
|
|
|
|
|
|
|
|
if (!list.Any())
|
2018-02-15 00:07:11 +01:00
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
await ReplyAsync($"No {type} found on this server");
|
|
|
|
|
return;
|
2018-02-15 00:07:11 +01:00
|
|
|
|
}
|
2017-10-03 00:22:26 +02:00
|
|
|
|
|
2018-06-13 22:18:57 +02:00
|
|
|
|
int guildMessages = 0;
|
|
|
|
|
if (type == RankType.messages)
|
|
|
|
|
{
|
2018-08-26 00:31:59 +02:00
|
|
|
|
// guildMessages = _database.Messages
|
|
|
|
|
// .Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong()))
|
|
|
|
|
// .Select(e => e.MessageCount)
|
|
|
|
|
// .Sum();
|
|
|
|
|
guildMessages = (int) _redis.Db.HashGet($"{Context.Guild.Id}:Messages", 0.ToString());
|
2018-06-13 22:18:57 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-10 17:56:43 +02:00
|
|
|
|
var highscoreUsers = new Dictionary<RankUserDto, int>();
|
2017-10-03 00:22:26 +02:00
|
|
|
|
var failedToRetrieveUser = false;
|
2018-05-10 17:56:43 +02:00
|
|
|
|
foreach (var user in list)
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
var guildUser = _userRepository.Get(user.Key);
|
2018-05-10 02:00:26 +02:00
|
|
|
|
if (guildUser?.Username != null)
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
highscoreUsers.Add(new RankUserDto
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
|
|
|
|
Username = guildUser.Username,
|
|
|
|
|
Discriminator = guildUser.Discriminator
|
2018-05-10 17:56:43 +02:00
|
|
|
|
}, user.Value);
|
2017-10-03 00:22:26 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
highscoreUsers.Add(new RankUserDto
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
Id = user.Key.ToString()
|
|
|
|
|
}, user.Value);
|
2017-10-03 00:22:26 +02:00
|
|
|
|
failedToRetrieveUser = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-10 17:56:43 +02:00
|
|
|
|
catch
|
2017-10-03 00:22:26 +02:00
|
|
|
|
{
|
2018-05-10 17:56:43 +02:00
|
|
|
|
// ignore
|
2017-10-03 00:22:26 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2018-08-26 17:39:01 +02:00
|
|
|
|
if (failedToRetrieveUser) replyBuilder.AppendLine(":warning: I couldn't find all usernames. Maybe they left the server?\n");
|
2018-06-13 22:18:57 +02:00
|
|
|
|
replyBuilder.AppendLine($":bar_chart: **{type.ToString().CapitalizeFirst()} Highscore for {Context.Guild.Name}**");
|
2017-10-03 00:22:26 +02:00
|
|
|
|
var highscorePlace = 1;
|
|
|
|
|
foreach (var user in highscoreUsers)
|
|
|
|
|
{
|
2017-12-28 22:38:49 +01:00
|
|
|
|
replyBuilder.Append(highscorePlace < 11
|
2018-04-30 23:44:19 +02:00
|
|
|
|
? $"{_emojiConverter.NumberToEmoji(highscorePlace)} "
|
2017-12-28 22:38:49 +01:00
|
|
|
|
: $"`{highscorePlace}.` ");
|
|
|
|
|
|
|
|
|
|
replyBuilder.Append(user.Key.Username != null
|
|
|
|
|
? $"**{user.Key.Username}#{user.Key.Discriminator}**"
|
|
|
|
|
: $"**{user.Key.Id}**");
|
2018-06-13 22:18:57 +02:00
|
|
|
|
|
|
|
|
|
replyBuilder.Append(type == RankType.messages
|
|
|
|
|
? $" - {user.Value} {type} - {Math.Round((double) (100 * user.Value) / guildMessages, digits: 2)}%\n"
|
|
|
|
|
: $" - {user.Value} {type}\n");
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2017-10-03 00:22:26 +02:00
|
|
|
|
highscorePlace++;
|
|
|
|
|
}
|
2017-12-29 01:53:50 +01:00
|
|
|
|
|
2017-12-28 22:38:49 +01:00
|
|
|
|
await ReplyAsync(replyBuilder.ToString());
|
2017-10-03 00:22:26 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2018-06-13 22:18:57 +02:00
|
|
|
|
await _errorHandler.HandleCommandException(e, Context);
|
2017-10-03 00:22:26 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-10 17:56:43 +02:00
|
|
|
|
|
|
|
|
|
private Dictionary<ulong, int> GetMessageList(int amount)
|
|
|
|
|
{
|
2018-06-13 22:18:57 +02:00
|
|
|
|
// return _database.Messages
|
|
|
|
|
// .Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong()))
|
|
|
|
|
// .OrderByDescending(o => o.MessageCount)
|
|
|
|
|
// .Take(amount)
|
|
|
|
|
// .ToDictionary(key => key.UserId.AsUlong(), key => key.MessageCount);
|
2018-05-26 02:33:45 +02:00
|
|
|
|
return _redis.Db
|
2018-08-26 12:33:04 +02:00
|
|
|
|
.HashGetAll($"{Context.Guild.Id}:Messages")
|
2018-08-29 21:16:01 +02:00
|
|
|
|
.Where(user => !user.Name.Equals(0))
|
2018-08-26 00:31:59 +02:00
|
|
|
|
.OrderByDescending(s => s.Value)
|
2018-08-26 12:33:04 +02:00
|
|
|
|
.Take(amount)
|
2018-08-29 21:16:01 +02:00
|
|
|
|
.ToDictionary(user => ulong.Parse(user.Name), user => int.Parse(user.Value));
|
2018-05-10 17:56:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Dictionary<ulong, int> GetKarmaList(int amount)
|
|
|
|
|
{
|
2018-05-13 21:33:48 +02:00
|
|
|
|
return _database.Karma
|
2018-05-10 17:56:43 +02:00
|
|
|
|
.Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong()))
|
|
|
|
|
.OrderByDescending(o => o.Karma)
|
2018-05-13 21:33:48 +02:00
|
|
|
|
.Take(amount)
|
|
|
|
|
.ToDictionary(key => key.UserId.AsUlong(), key => key.Karma);
|
2018-05-10 17:56:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Dictionary<ulong, int> GetRollsList(int amount)
|
|
|
|
|
{
|
2018-05-13 21:33:48 +02:00
|
|
|
|
return _database.Rolls
|
2018-05-10 17:56:43 +02:00
|
|
|
|
.Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong()))
|
|
|
|
|
.OrderByDescending(o => o.Rolls)
|
2018-05-13 21:33:48 +02:00
|
|
|
|
.Take(amount)
|
|
|
|
|
.ToDictionary(key => key.UserId.AsUlong(), key => key.Rolls);
|
2018-05-10 17:56:43 +02:00
|
|
|
|
}
|
2017-10-03 00:22:26 +02:00
|
|
|
|
}
|
2017-04-12 21:49:04 +02:00
|
|
|
|
}
|