Fixed slow .xp
and .xpglb
This commit is contained in:
parent
067297478e
commit
48adfc19af
1949
src/NadekoBot/Migrations/20170913022654_total-xp.Designer.cs
generated
Normal file
1949
src/NadekoBot/Migrations/20170913022654_total-xp.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
src/NadekoBot/Migrations/20170913022654_total-xp.cs
Normal file
27
src/NadekoBot/Migrations/20170913022654_total-xp.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace NadekoBot.Migrations
|
||||||
|
{
|
||||||
|
public partial class totalxp : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "TotalXp",
|
||||||
|
table: "DiscordUser",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.Sql(MigrationQueries.TotalXp);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "TotalXp",
|
||||||
|
table: "DiscordUser");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,5 +34,9 @@ INSERT INTO DiscordUser
|
|||||||
FROM DiscordUser_tmp;
|
FROM DiscordUser_tmp;
|
||||||
|
|
||||||
DROP TABLE DiscordUser_tmp;";
|
DROP TABLE DiscordUser_tmp;";
|
||||||
|
public static string TotalXp { get; } =
|
||||||
|
@"UPDATE DiscordUser
|
||||||
|
SET TotalXp = (SELECT SUM(Xp) FROM UserXpStats WHERE UserId = DiscordUser.UserId)";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -464,12 +464,14 @@ namespace NadekoBot.Migrations
|
|||||||
|
|
||||||
b.Property<DateTime>("LastLevelUp")
|
b.Property<DateTime>("LastLevelUp")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasDefaultValue(new DateTime(2017, 9, 11, 22, 0, 31, 236, DateTimeKind.Local));
|
.HasDefaultValue(new DateTime(2017, 9, 13, 4, 26, 53, 906, DateTimeKind.Local));
|
||||||
|
|
||||||
b.Property<DateTime>("LastXpGain");
|
b.Property<DateTime>("LastXpGain");
|
||||||
|
|
||||||
b.Property<int>("NotifyOnLevelUp");
|
b.Property<int>("NotifyOnLevelUp");
|
||||||
|
|
||||||
|
b.Property<int>("TotalXp");
|
||||||
|
|
||||||
b.Property<ulong>("UserId");
|
b.Property<ulong>("UserId");
|
||||||
|
|
||||||
b.Property<string>("Username");
|
b.Property<string>("Username");
|
||||||
@ -1362,7 +1364,7 @@ namespace NadekoBot.Migrations
|
|||||||
|
|
||||||
b.Property<DateTime>("LastLevelUp")
|
b.Property<DateTime>("LastLevelUp")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasDefaultValue(new DateTime(2017, 9, 11, 22, 0, 31, 238, DateTimeKind.Local));
|
.HasDefaultValue(new DateTime(2017, 9, 13, 4, 26, 53, 910, DateTimeKind.Local));
|
||||||
|
|
||||||
b.Property<int>("NotifyOnLevelUp");
|
b.Property<int>("NotifyOnLevelUp");
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
|
|
||||||
var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
|
var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
|
||||||
usr.Xp += xp;
|
usr.Xp += xp;
|
||||||
|
du.TotalXp += xp;
|
||||||
if (du.Club != null)
|
if (du.Club != null)
|
||||||
du.Club.Xp += xp;
|
du.Club.Xp += xp;
|
||||||
var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
|
var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
|
||||||
@ -311,7 +312,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
{
|
{
|
||||||
using (var uow = _db.UnitOfWork)
|
using (var uow = _db.UnitOfWork)
|
||||||
{
|
{
|
||||||
return uow.Xp.GetUsersFor(page);
|
return uow.DiscordUsers.GetUsersXpLeaderboardFor(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,8 +425,8 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
{
|
{
|
||||||
du = uow.DiscordUsers.GetOrCreate(user);
|
du = uow.DiscordUsers.GetOrCreate(user);
|
||||||
stats = uow.Xp.GetOrCreateUser(user.GuildId, user.Id);
|
stats = uow.Xp.GetOrCreateUser(user.GuildId, user.Id);
|
||||||
totalXp = uow.Xp.GetTotalUserXp(user.Id);
|
totalXp = du.TotalXp;
|
||||||
globalRank = uow.Xp.GetUserGlobalRanking(user.Id);
|
globalRank = uow.DiscordUsers.GetUserGlobalRanking(user.Id);
|
||||||
guildRank = uow.Xp.GetUserGuildRanking(user.Id, user.GuildId);
|
guildRank = uow.Xp.GetUserGuildRanking(user.Id, user.GuildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
using NadekoBot.Common;
|
||||||
using NadekoBot.Common.Attributes;
|
using NadekoBot.Common.Attributes;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
using NadekoBot.Modules.Xp.Common;
|
using NadekoBot.Modules.Xp.Common;
|
||||||
using NadekoBot.Modules.Xp.Services;
|
using NadekoBot.Modules.Xp.Services;
|
||||||
|
using NadekoBot.Services;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -15,14 +17,42 @@ namespace NadekoBot.Modules.Xp
|
|||||||
public partial class Xp : NadekoTopLevelModule<XpService>
|
public partial class Xp : NadekoTopLevelModule<XpService>
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
private readonly DbService _db;
|
||||||
|
|
||||||
public Xp(DiscordSocketClient client)
|
public Xp(DiscordSocketClient client,DbService db)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
|
_db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
//[RequireContext(ContextType.Guild)]
|
||||||
|
//[OwnerOnly]
|
||||||
|
//public async Task Populate()
|
||||||
|
//{
|
||||||
|
// var rng = new NadekoRandom();
|
||||||
|
// using (var uow = _db.UnitOfWork)
|
||||||
|
// {
|
||||||
|
// for (var i = 0ul; i < 1000000; i++)
|
||||||
|
// {
|
||||||
|
// uow.DiscordUsers.Add(new DiscordUser()
|
||||||
|
// {
|
||||||
|
// AvatarId = i.ToString(),
|
||||||
|
// Discriminator = "1234",
|
||||||
|
// UserId = i,
|
||||||
|
// Username = i.ToString(),
|
||||||
|
// Club = null,
|
||||||
|
// });
|
||||||
|
// var xp = uow.Xp.GetOrCreateUser(Context.Guild.Id, i);
|
||||||
|
// xp.Xp = rng.Next(100, 100000);
|
||||||
|
// }
|
||||||
|
// uow.Complete();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
//[Ratelimit(30)]
|
||||||
public async Task Experience([Remainder]IUser user = null)
|
public async Task Experience([Remainder]IUser user = null)
|
||||||
{
|
{
|
||||||
user = user ?? Context.User;
|
user = user ?? Context.User;
|
||||||
@ -44,7 +74,7 @@ namespace NadekoBot.Modules.Xp
|
|||||||
{
|
{
|
||||||
page--;
|
page--;
|
||||||
|
|
||||||
if (page < 0)
|
if (page < 0 || page > 100)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
var roles = _service.GetRoleRewards(Context.Guild.Id)
|
var roles = _service.GetRoleRewards(Context.Guild.Id)
|
||||||
@ -173,7 +203,7 @@ namespace NadekoBot.Modules.Xp
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public Task XpLeaderboard(int page = 1)
|
public Task XpLeaderboard(int page = 1)
|
||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0 || page > 100)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
return Context.Channel.SendPaginatedConfirmAsync(_client, page, async (curPage) =>
|
return Context.Channel.SendPaginatedConfirmAsync(_client, page, async (curPage) =>
|
||||||
@ -214,32 +244,28 @@ namespace NadekoBot.Modules.Xp
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task XpGlobalLeaderboard(int page = 1)
|
public async Task XpGlobalLeaderboard(int page = 1)
|
||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0 || page > 100)
|
||||||
return;
|
return;
|
||||||
|
var users = _service.GetUserXps(page);
|
||||||
|
|
||||||
await Context.Channel.SendPaginatedConfirmAsync(_client, page, async (curPage) =>
|
var embed = new EmbedBuilder()
|
||||||
|
.WithTitle(GetText("global_leaderboard"))
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
|
if (!users.Any())
|
||||||
|
embed.WithDescription("-");
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var users = _service.GetUserXps(curPage);
|
for (int i = 0; i < users.Length; i++)
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
|
||||||
.WithTitle(GetText("global_leaderboard"))
|
|
||||||
.WithOkColor();
|
|
||||||
|
|
||||||
if (!users.Any())
|
|
||||||
return embed.WithDescription("-");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < users.Length; i++)
|
var user = await Context.Guild.GetUserAsync(users[i].UserId).ConfigureAwait(false);
|
||||||
{
|
embed.AddField(
|
||||||
var user = await Context.Guild.GetUserAsync(users[i].UserId).ConfigureAwait(false);
|
$"#{(i + 1 + page * 9)} {(user?.ToString() ?? users[i].UserId.ToString())}",
|
||||||
embed.AddField(
|
$"{GetText("level_x", LevelStats.FromXp(users[i].TotalXp).Level)} - {users[i].TotalXp}xp");
|
||||||
$"#{(i + 1 + curPage * 9)} {(user?.ToString() ?? users[i].UserId.ToString())}",
|
|
||||||
$"{GetText("level_x", LevelStats.FromXp(users[i].TotalXp).Level)} - {users[i].TotalXp}xp");
|
|
||||||
}
|
|
||||||
|
|
||||||
return embed;
|
|
||||||
}
|
}
|
||||||
}, addPaginatedFooter: false);
|
}
|
||||||
|
|
||||||
|
await Context.Channel.EmbedAsync(embed);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
@ -3589,7 +3589,7 @@
|
|||||||
<value>`{0}xpex Role Excluded-Role` `{0}xpex Server`</value>
|
<value>`{0}xpex Role Excluded-Role` `{0}xpex Server`</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="xpexclude_desc" xml:space="preserve">
|
<data name="xpexclude_desc" xml:space="preserve">
|
||||||
<value>Exclude a user or a role from the xp system, or whole current server.</value>
|
<value>Exclude a channel, role or current server from the xp system.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="xpnotify_cmd" xml:space="preserve">
|
<data name="xpnotify_cmd" xml:space="preserve">
|
||||||
<value>xpnotify xpn</value>
|
<value>xpnotify xpn</value>
|
||||||
|
@ -10,6 +10,8 @@ namespace NadekoBot.Services.Database.Models
|
|||||||
public string AvatarId { get; set; }
|
public string AvatarId { get; set; }
|
||||||
|
|
||||||
public ClubInfo Club { get; set; }
|
public ClubInfo Club { get; set; }
|
||||||
|
|
||||||
|
public int TotalXp { get; set; }
|
||||||
public DateTime LastLevelUp { get; set; } = DateTime.UtcNow;
|
public DateTime LastLevelUp { get; set; } = DateTime.UtcNow;
|
||||||
public DateTime LastXpGain { get; set; } = DateTime.MinValue;
|
public DateTime LastXpGain { get; set; } = DateTime.MinValue;
|
||||||
public XpNotificationType NotifyOnLevelUp { get; set; }
|
public XpNotificationType NotifyOnLevelUp { get; set; }
|
||||||
|
@ -6,5 +6,7 @@ namespace NadekoBot.Services.Database.Repositories
|
|||||||
public interface IDiscordUserRepository : IRepository<DiscordUser>
|
public interface IDiscordUserRepository : IRepository<DiscordUser>
|
||||||
{
|
{
|
||||||
DiscordUser GetOrCreate(IUser original);
|
DiscordUser GetOrCreate(IUser original);
|
||||||
|
int GetUserGlobalRanking(ulong id);
|
||||||
|
(ulong UserId, int TotalXp)[] GetUsersXpLeaderboardFor(int page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,7 @@ namespace NadekoBot.Services.Database.Repositories
|
|||||||
{
|
{
|
||||||
UserXpStats GetOrCreateUser(ulong guildId, ulong userId);
|
UserXpStats GetOrCreateUser(ulong guildId, ulong userId);
|
||||||
int GetTotalUserXp(ulong userId);
|
int GetTotalUserXp(ulong userId);
|
||||||
UserXpStats[] GetUsersFor(ulong guildId, int page);
|
|
||||||
(ulong UserId, int TotalXp)[] GetUsersFor(int page);
|
|
||||||
int GetUserGlobalRanking(ulong userId);
|
|
||||||
int GetUserGuildRanking(ulong userId, ulong guildId);
|
int GetUserGuildRanking(ulong userId, ulong guildId);
|
||||||
|
UserXpStats[] GetUsersFor(ulong guildId, int page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,5 +37,24 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
|||||||
|
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetUserGlobalRanking(ulong id)
|
||||||
|
{
|
||||||
|
return _set.Count(x => x.TotalXp >
|
||||||
|
_set.Where(y => y.UserId == id)
|
||||||
|
.DefaultIfEmpty()
|
||||||
|
.Sum(y => y.TotalXp));
|
||||||
|
}
|
||||||
|
|
||||||
|
public (ulong UserId, int TotalXp)[] GetUsersXpLeaderboardFor(int page)
|
||||||
|
{
|
||||||
|
return _set
|
||||||
|
.OrderByDescending(x => x.TotalXp)
|
||||||
|
.Skip(page * 9)
|
||||||
|
.Take(9)
|
||||||
|
.AsEnumerable()
|
||||||
|
.Select(y => (y.UserId, y.TotalXp))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,15 +43,6 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetUserGlobalRanking(ulong userId)
|
|
||||||
{
|
|
||||||
return _set
|
|
||||||
.GroupBy(x => x.UserId)
|
|
||||||
.Count(x => x.Sum(y => y.Xp) > _set
|
|
||||||
.Where(y => y.UserId == userId)
|
|
||||||
.Sum(y => y.Xp)) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetUserGuildRanking(ulong userId, ulong guildId)
|
public int GetUserGuildRanking(ulong userId, ulong guildId)
|
||||||
{
|
{
|
||||||
return _set
|
return _set
|
||||||
@ -62,16 +53,5 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
|||||||
.DefaultIfEmpty()
|
.DefaultIfEmpty()
|
||||||
.Sum())) + 1;
|
.Sum())) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public (ulong UserId, int TotalXp)[] GetUsersFor(int page)
|
|
||||||
{
|
|
||||||
return _set.GroupBy(x => x.UserId)
|
|
||||||
.OrderByDescending(x => x.Sum(y => y.Xp))
|
|
||||||
.Skip(page * 9)
|
|
||||||
.Take(9)
|
|
||||||
.AsEnumerable()
|
|
||||||
.Select(x => (x.Key, x.Sum(y => y.Xp)))
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user