Revert "Fixed .crypto - some extra fields which were causing deserialization issues"

This reverts commit f65ba100af.
This commit is contained in:
Kwoth
2022-06-17 14:03:30 +02:00
parent f65ba100af
commit 3744dd287c
6 changed files with 188 additions and 294 deletions

View File

@@ -57,6 +57,6 @@ public sealed class QueueRunner
} }
} }
public ValueTask EnqueueAsync(Func<Task> action) public ValueTask Enqueue(Func<Task> action)
=> _channel.Writer.WriteAsync(action); => _channel.Writer.WriteAsync(action);
} }

View File

@@ -138,9 +138,9 @@ public class CryptoService : INService
using var http = _httpFactory.CreateClient(); using var http = _httpFactory.CreateClient();
var strData = await http.GetFromJsonAsync<CryptoResponse>( var strData = await http.GetFromJsonAsync<CryptoResponse>(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?" "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?"
+ $"CMC_PRO_API_KEY=e79ec505-0913-439d-ae07-069e296a6079" + $"CMC_PRO_API_KEY={_creds.CoinmarketcapApiKey}"
+ "&start=1" + "&start=1"
+ "&limit=5" + "&limit=5000"
+ "&convert=USD"); + "&convert=USD");
return JsonSerializer.Serialize(strData); return JsonSerializer.Serialize(strData);

View File

@@ -16,11 +16,11 @@ public class CmcQuote
[JsonPropertyName("volume_24h")] [JsonPropertyName("volume_24h")]
public double Volume24h { get; set; } public double Volume24h { get; set; }
// [JsonPropertyName("volume_change_24h")] [JsonPropertyName("volume_change_24h")]
// public double VolumeChange24h { get; set; } public double VolumeChange24h { get; set; }
//
// [JsonPropertyName("percent_change_1h")] [JsonPropertyName("percent_change_1h")]
// public double PercentChange1h { get; set; } public double PercentChange1h { get; set; }
[JsonPropertyName("percent_change_24h")] [JsonPropertyName("percent_change_24h")]
public double PercentChange24h { get; set; } public double PercentChange24h { get; set; }
@@ -33,6 +33,12 @@ public class CmcQuote
[JsonPropertyName("market_cap_dominance")] [JsonPropertyName("market_cap_dominance")]
public double MarketCapDominance { get; set; } public double MarketCapDominance { get; set; }
[JsonPropertyName("fully_diluted_market_cap")]
public double FullyDilutedMarketCap { get; set; }
[JsonPropertyName("last_updated")]
public DateTime LastUpdated { get; set; }
} }
public class CmcResponseData public class CmcResponseData
@@ -52,6 +58,9 @@ public class CmcResponseData
[JsonPropertyName("cmc_rank")] [JsonPropertyName("cmc_rank")]
public int CmcRank { get; set; } public int CmcRank { get; set; }
[JsonPropertyName("num_market_pairs")]
public int NumMarketPairs { get; set; }
[JsonPropertyName("circulating_supply")] [JsonPropertyName("circulating_supply")]
public double? CirculatingSupply { get; set; } public double? CirculatingSupply { get; set; }
@@ -61,6 +70,15 @@ public class CmcResponseData
[JsonPropertyName("max_supply")] [JsonPropertyName("max_supply")]
public double? MaxSupply { get; set; } public double? MaxSupply { get; set; }
[JsonPropertyName("last_updated")]
public DateTime LastUpdated { get; set; }
[JsonPropertyName("date_added")]
public DateTime DateAdded { get; set; }
[JsonPropertyName("tags")]
public List<string> Tags { get; set; }
[JsonPropertyName("quote")] [JsonPropertyName("quote")]
public Dictionary<string, CmcQuote> Quote { get; set; } public Dictionary<string, CmcQuote> Quote { get; set; }
} }

View File

@@ -221,7 +221,7 @@ public class StreamRoleService : IReadyExecutor, INService
} }
private async ValueTask RescanUser(IGuildUser user, StreamRoleSettings setting, IRole addRole = null) private async ValueTask RescanUser(IGuildUser user, StreamRoleSettings setting, IRole addRole = null)
=> await _queueRunner.EnqueueAsync(() => RescanUserInternal(user, setting, addRole)); => await _queueRunner.Enqueue(() => RescanUserInternal(user, setting, addRole));
private async Task RescanUserInternal(IGuildUser user, StreamRoleSettings setting, IRole addRole = null) private async Task RescanUserInternal(IGuildUser user, StreamRoleSettings setting, IRole addRole = null)
{ {
@@ -239,7 +239,7 @@ public class StreamRoleService : IReadyExecutor, INService
&& setting.Blacklist.All(x => x.UserId != user.Id) && setting.Blacklist.All(x => x.UserId != user.Id)
&& user.RoleIds.Contains(setting.FromRoleId)) && user.RoleIds.Contains(setting.FromRoleId))
{ {
await _queueRunner.EnqueueAsync(async () => await _queueRunner.Enqueue(async () =>
{ {
try try
{ {
@@ -277,7 +277,7 @@ public class StreamRoleService : IReadyExecutor, INService
//check if user is in the addrole //check if user is in the addrole
if (user.RoleIds.Contains(setting.AddRoleId)) if (user.RoleIds.Contains(setting.AddRoleId))
{ {
await _queueRunner.EnqueueAsync(async () => await _queueRunner.Enqueue(async () =>
{ {
try try
{ {

View File

@@ -1,6 +1,4 @@
#nullable disable #nullable disable
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Db; using NadekoBot.Db;
@@ -15,7 +13,6 @@ using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
using StackExchange.Redis; using StackExchange.Redis;
using System.Threading.Channels;
using Color = SixLabors.ImageSharp.Color; using Color = SixLabors.ImageSharp.Color;
using Image = SixLabors.ImageSharp.Image; using Image = SixLabors.ImageSharp.Image;
@@ -42,6 +39,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedChannels; private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedChannels;
private readonly ConcurrentHashSet<ulong> _excludedServers; private readonly ConcurrentHashSet<ulong> _excludedServers;
private readonly ConcurrentQueue<UserCacheItem> _addMessageXp = new();
private XpTemplate template; private XpTemplate template;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
@@ -129,199 +127,144 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
using var timer = new PeriodicTimer(5.Seconds()); using var timer = new PeriodicTimer(5.Seconds());
while (await timer.WaitForNextTickAsync()) while (await timer.WaitForNextTickAsync())
{ {
await UpdateXp(); await UpdateLoop();
} }
} }
private async Task UpdateLoop()
private readonly QueueRunner _levelUpQueue = new QueueRunner(0, 50);
private readonly Channel<UserCacheItem> _xpGainQueue = Channel.CreateUnbounded<UserCacheItem>();
private async Task UpdateXp()
{ {
try try
{ {
var reader = _xpGainQueue.Reader; var toNotify =
new List<(IGuild Guild, IMessageChannel MessageChannel, IUser User, long Level,
XpNotificationLocation NotifyType, NotifOf NotifOf)>();
var roleRewards = new Dictionary<ulong, List<XpRoleReward>>();
var curRewards = new Dictionary<ulong, List<XpCurrencyReward>>();
// no elements, quick return var toAddTo = new List<UserCacheItem>();
if (!reader.TryPeek(out _)) while (_addMessageXp.TryDequeue(out var usr))
toAddTo.Add(usr);
var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, x.User));
if (toAddTo.Count == 0)
return; return;
await using var ctx = _db.GetDbContext(); await using (var uow = _db.GetDbContext())
await using var tran = await ctx.Database.BeginTransactionAsync();
var userAdds = new Dictionary<ulong, int>();
while (reader.TryRead(out var item))
{ {
// // update xp foreach (var item in group)
// await ctx.GetTable<UserXpStats>()
// .Where(x => x.UserId == item.User.Id)
// .UpdateWithOutputAsync(old => new()
// {
// Xp = old.Xp + item.XpAmount
// }, (o, n) => n);
var user = item.User;
var du = await ctx.GetTable<DiscordUser>()
.Where(x => x.UserId == user.Id)
.UpdateWithOutputAsync(
old => new()
{ {
TotalXp = old.TotalXp + item.XpAmount var xp = item.Sum(x => x.XpAmount);
},
(_, n) => n); var usr = uow.GetOrCreateUserXpStats(item.Key.GuildId, item.Key.User.Id);
var du = uow.GetOrCreateUser(item.Key.User);
var globalXp = du.TotalXp;
var oldGlobalLevelData = new LevelStats(globalXp);
var newGlobalLevelData = new LevelStats(globalXp + xp);
var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
usr.Xp += xp;
du.TotalXp += xp;
if (du.Club is not null)
du.Club.Xp += xp;
var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
if (oldGlobalLevelData.Level < newGlobalLevelData.Level)
{
var first = item.First();
if (du.NotifyOnLevelUp != XpNotificationLocation.None)
{
toNotify.Add((first.Guild, first.Channel, first.User, newGlobalLevelData.Level,
du.NotifyOnLevelUp, NotifOf.Global));
}
} }
await tran.CommitAsync(); if (oldGuildLevelData.Level < newGuildLevelData.Level)
{
//send level up notification
var first = item.First();
if (usr.NotifyOnLevelUp != XpNotificationLocation.None)
{
toNotify.Add((first.Guild, first.Channel, first.User, newGuildLevelData.Level,
usr.NotifyOnLevelUp, NotifOf.Server));
}
var users = await ctx.GetTable<DiscordUser>() //give role
.Where(x => userAdds.Keys.Contains(x.UserId)) if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
.ToListAsyncLinqToDB(); {
rrews = uow.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
roleRewards.Add(usr.GuildId, rrews);
}
// foreach (var user in users) if (!curRewards.TryGetValue(usr.GuildId, out var crews))
// { {
// var oldLevel = new LevelStats(user.TotalXp - userAdds[user.UserId]); crews = uow.XpSettingsFor(usr.GuildId).CurrencyRewards.ToList();
// var newLevel = new LevelStats(user.TotalXp); curRewards.Add(usr.GuildId, crews);
// }
// if (oldLevel.Level != newLevel.Level)
// {
// await _levelUpQueue.EnqueueAsync(
// NotifyUser(user.UserId,
// user.NotifyOnLevelUp));
// }
// }
return; //loop through levels since last level up, so if a high amount of xp is gained, reward are still applied.
// var toNotify = for (var i = oldGuildLevelData.Level + 1; i <= newGuildLevelData.Level; i++)
// new List<(IGuild Guild, IMessageChannel MessageChannel, IUser User, long Level, {
// XpNotificationLocation NotifyType, NotifOf NotifOf)>(); var rrew = rrews.FirstOrDefault(x => x.Level == i);
// var roleRewards = new Dictionary<ulong, List<XpRoleReward>>(); if (rrew is not null)
// var curRewards = new Dictionary<ulong, List<XpCurrencyReward>>(); {
// var role = first.User.Guild.GetRole(rrew.RoleId);
// var toAddTo = new List<UserCacheItem>(); if (role is not null)
// while (_addMessageXp.TryDequeue(out var usr)) {
// toAddTo.Add(usr); if (rrew.Remove)
// _ = first.User.RemoveRoleAsync(role);
// var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, x.User)); else
// if (toAddTo.Count == 0) _ = first.User.AddRoleAsync(role);
// return; }
// }
// await using (var uow = _db.GetDbContext())
// { //get currency reward for this level
// foreach (var item in group) var crew = crews.FirstOrDefault(x => x.Level == i);
// { if (crew is not null)
// var xp = item.Sum(x => x.XpAmount); //give the user the reward if it exists
// await _cs.AddAsync(item.Key.User.Id, crew.Amount, new("xp", "level-up"));
// var usr = uow.GetOrCreateUserXpStats(item.Key.GuildId, item.Key.User.Id); }
// var du = uow.GetOrCreateUser(item.Key.User); }
// }
// var globalXp = du.TotalXp;
// var oldGlobalLevelData = new LevelStats(globalXp); uow.SaveChanges();
// var newGlobalLevelData = new LevelStats(globalXp + xp); }
//
// var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp); await toNotify.Select(async x =>
// usr.Xp += xp; {
// du.TotalXp += xp; if (x.NotifOf == NotifOf.Server)
// if (du.Club is not null) {
// du.Club.Xp += xp; if (x.NotifyType == XpNotificationLocation.Dm)
// var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp); {
// await x.User.SendConfirmAsync(_eb,
// if (oldGlobalLevelData.Level < newGlobalLevelData.Level) _strings.GetText(strs.level_up_dm(x.User.Mention,
// { Format.Bold(x.Level.ToString()),
// var first = item.First(); Format.Bold(x.Guild.ToString() ?? "-")),
// if (du.NotifyOnLevelUp != XpNotificationLocation.None) x.Guild.Id));
// { }
// toNotify.Add((first.Guild, first.Channel, first.User, newGlobalLevelData.Level, else if (x.MessageChannel is not null) // channel
// du.NotifyOnLevelUp, NotifOf.Global)); {
// } await x.MessageChannel.SendConfirmAsync(_eb,
// } _strings.GetText(strs.level_up_channel(x.User.Mention,
// Format.Bold(x.Level.ToString())),
// if (oldGuildLevelData.Level < newGuildLevelData.Level) x.Guild.Id));
// { }
// //send level up notification }
// var first = item.First(); else
// if (usr.NotifyOnLevelUp != XpNotificationLocation.None) {
// { IMessageChannel chan;
// toNotify.Add((first.Guild, first.Channel, first.User, newGuildLevelData.Level, if (x.NotifyType == XpNotificationLocation.Dm)
// usr.NotifyOnLevelUp, NotifOf.Server)); chan = await x.User.CreateDMChannelAsync();
// } else // channel
// chan = x.MessageChannel;
// //give role
// if (!roleRewards.TryGetValue(usr.GuildId, out var rrews)) await chan.SendConfirmAsync(_eb,
// { _strings.GetText(strs.level_up_global(x.User.Mention,
// rrews = uow.XpSettingsFor(usr.GuildId).RoleRewards.ToList(); Format.Bold(x.Level.ToString())),
// roleRewards.Add(usr.GuildId, rrews); x.Guild.Id));
// } }
// })
// if (!curRewards.TryGetValue(usr.GuildId, out var crews)) .WhenAll();
// {
// crews = uow.XpSettingsFor(usr.GuildId).CurrencyRewards.ToList();
// curRewards.Add(usr.GuildId, crews);
// }
//
// //loop through levels since last level up, so if a high amount of xp is gained, reward are still applied.
// for (var i = oldGuildLevelData.Level + 1; i <= newGuildLevelData.Level; i++)
// {
// var rrew = rrews.FirstOrDefault(x => x.Level == i);
// if (rrew is not null)
// {
// var role = first.User.Guild.GetRole(rrew.RoleId);
// if (role is not null)
// {
// if (rrew.Remove)
// _ = first.User.RemoveRoleAsync(role);
// else
// _ = first.User.AddRoleAsync(role);
// }
// }
//
// //get currency reward for this level
// var crew = crews.FirstOrDefault(x => x.Level == i);
// if (crew is not null)
// //give the user the reward if it exists
// await _cs.AddAsync(item.Key.User.Id, crew.Amount, new("xp", "level-up"));
// }
// }
// }
//
// uow.SaveChanges();
// }
//
// await toNotify.Select(async x =>
// {
// if (x.NotifOf == NotifOf.Server)
// {
// if (x.NotifyType == XpNotificationLocation.Dm)
// {
// await x.User.SendConfirmAsync(_eb,
// _strings.GetText(strs.level_up_dm(x.User.Mention,
// Format.Bold(x.Level.ToString()),
// Format.Bold(x.Guild.ToString() ?? "-")),
// x.Guild.Id));
// }
// else if (x.MessageChannel is not null) // channel
// {
// await x.MessageChannel.SendConfirmAsync(_eb,
// _strings.GetText(strs.level_up_channel(x.User.Mention,
// Format.Bold(x.Level.ToString())),
// x.Guild.Id));
// }
// }
// else
// {
// IMessageChannel chan;
// if (x.NotifyType == XpNotificationLocation.Dm)
// chan = await x.User.CreateDMChannelAsync();
// else // channel
// chan = x.MessageChannel;
//
// await chan.SendConfirmAsync(_eb,
// _strings.GetText(strs.level_up_global(x.User.Mention,
// Format.Bold(x.Level.ToString())),
// x.Guild.Id));
// }
// })
// .WhenAll();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -329,69 +272,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
} }
} }
private Func<Task> NotifyUser(
ulong guildId,
ulong channelId,
ulong userId,
bool isServer,
int level,
XpNotificationLocation notifyLoc)
=> async () =>
{
var notify = HandleNotifyInternalAsync(guildId, channelId, userId, isServer, level, notifyLoc);
await Task.WhenAll(notify);
};
private async Task HandleNotifyInternalAsync(ulong guildId, ulong channelId, ulong userId, bool isServer, int level,
XpNotificationLocation notifyLoc)
{
var user = await _client.GetUserAsync(userId);
var guild = _client.GetGuild(guildId);
var ch = guild?.GetTextChannel(channelId);
if (user is null || guild is null)
return;
if (isServer)
{
if (notifyLoc == XpNotificationLocation.Dm)
{
await user.SendConfirmAsync(_eb,
_strings.GetText(strs.level_up_dm(user.Mention,
Format.Bold(level.ToString()),
Format.Bold(guild.ToString() ?? "-")),
guild.Id));
}
else // channel
{
await ch.SendConfirmAsync(_eb,
_strings.GetText(strs.level_up_channel(user.Mention,
Format.Bold(level.ToString())),
guild.Id));
}
}
else // global level
{
var chan = notifyLoc switch
{
XpNotificationLocation.Dm => (IMessageChannel)await user.CreateDMChannelAsync(),
XpNotificationLocation.Channel => ch,
_ => null
};
if (chan is null)
return;
await chan.SendConfirmAsync(_eb,
_strings.GetText(strs.level_up_global(user.Mention,
Format.Bold(level.ToString())),
guild.Id));
}
}
private const string XP_TEMPLATE_PATH = "./data/xp_template.json"; private const string XP_TEMPLATE_PATH = "./data/xp_template.json";
private void InternalReloadXpTemplate() private void InternalReloadXpTemplate()
{ {
try try
@@ -416,8 +297,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
{ {
Log.Warning("Loaded default xp_template.json values as the old one was version 0. " Log.Warning("Loaded default xp_template.json values as the old one was version 0. "
+ "Old one was renamed to xp_template.json.old"); + "Old one was renamed to xp_template.json.old");
File.WriteAllText("./data/xp_template.json.old", File.WriteAllText("./data/xp_template.json.old", JsonConvert.SerializeObject(template, Formatting.Indented));
JsonConvert.SerializeObject(template, Formatting.Indented));
template = new(); template = new();
template.Version = 1; template.Version = 1;
File.WriteAllText(XP_TEMPLATE_PATH, JsonConvert.SerializeObject(template, Formatting.Indented)); File.WriteAllText(XP_TEMPLATE_PATH, JsonConvert.SerializeObject(template, Formatting.Indented));
@@ -587,7 +467,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
if (socketUser is not SocketGuildUser user || user.IsBot) if (socketUser is not SocketGuildUser user || user.IsBot)
return Task.CompletedTask; return Task.CompletedTask;
_ = Task.Run(async () => _ = Task.Run(() =>
{ {
if (before.VoiceChannel is not null) if (before.VoiceChannel is not null)
ScanChannelForVoiceXp(before.VoiceChannel); ScanChannelForVoiceXp(before.VoiceChannel);
@@ -595,17 +475,15 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
if (after.VoiceChannel is not null && after.VoiceChannel != before.VoiceChannel) if (after.VoiceChannel is not null && after.VoiceChannel != before.VoiceChannel)
ScanChannelForVoiceXp(after.VoiceChannel); ScanChannelForVoiceXp(after.VoiceChannel);
else if (after.VoiceChannel is null) else if (after.VoiceChannel is null)
{
// In this case, the user left the channel and the previous for loops didn't catch // In this case, the user left the channel and the previous for loops didn't catch
// it because it wasn't in any new channel. So we need to get rid of it. // it because it wasn't in any new channel. So we need to get rid of it.
await UserLeftVoiceChannel(user, before.VoiceChannel); UserLeftVoiceChannel(user, before.VoiceChannel);
}
}); });
return Task.CompletedTask; return Task.CompletedTask;
} }
private async Task ScanChannelForVoiceXp(SocketVoiceChannel channel) private void ScanChannelForVoiceXp(SocketVoiceChannel channel)
{ {
if (ShouldTrackVoiceChannel(channel)) if (ShouldTrackVoiceChannel(channel))
{ {
@@ -615,7 +493,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
else else
{ {
foreach (var user in channel.Users) foreach (var user in channel.Users)
await UserLeftVoiceChannel(user, channel); UserLeftVoiceChannel(user, channel);
} }
} }
@@ -650,7 +528,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
when: When.NotExists); when: When.NotExists);
} }
private async Task UserLeftVoiceChannel(SocketGuildUser user, SocketVoiceChannel channel) private void UserLeftVoiceChannel(SocketGuildUser user, SocketVoiceChannel channel)
{ {
var key = $"{_creds.RedisKey()}_user_xp_vc_join_{user.Id}"; var key = $"{_creds.RedisKey()}_user_xp_vc_join_{user.Id}";
var value = _cache.Redis.GetDatabase().StringGet(key); var value = _cache.Redis.GetDatabase().StringGet(key);
@@ -671,7 +549,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
if (actualXp > 0) if (actualXp > 0)
{ {
await _xpGainQueue.Writer.WriteAsync(new() _addMessageXp.Enqueue(new()
{ {
Guild = channel.Guild, Guild = channel.Guild,
User = user, User = user,
@@ -718,7 +596,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
if (!SetUserRewarded(user.Id)) if (!SetUserRewarded(user.Id))
return; return;
_xpGainQueue.Writer.WriteAsync(new() _addMessageXp.Enqueue(new()
{ {
Guild = user.Guild, Guild = user.Guild,
Channel = arg.Channel, Channel = arg.Channel,
@@ -729,19 +607,19 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
return Task.CompletedTask; return Task.CompletedTask;
} }
// public void AddXpDirectly(IGuildUser user, IMessageChannel channel, int amount) public void AddXpDirectly(IGuildUser user, IMessageChannel channel, int amount)
// { {
// if (amount <= 0) if (amount <= 0)
// throw new ArgumentOutOfRangeException(nameof(amount)); throw new ArgumentOutOfRangeException(nameof(amount));
//
// _xpGainQueue.Writer.WriteAsync(new() _addMessageXp.Enqueue(new()
// { {
// Guild = user.Guild, Guild = user.Guild,
// Channel = channel, Channel = channel,
// User = user, User = user,
// XpAmount = amount XpAmount = amount
// }); });
// } }
public void AddXp(ulong userId, ulong guildId, int amount) public void AddXp(ulong userId, ulong guildId, int amount)
{ {
@@ -777,8 +655,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
var r = _cache.Redis.GetDatabase(); var r = _cache.Redis.GetDatabase();
var key = $"{_creds.RedisKey()}_user_xp_gain_{userId}"; var key = $"{_creds.RedisKey()}_user_xp_gain_{userId}";
// todo remove this return
return true;
return r.StringSet(key, return r.StringSet(key,
true, true,
TimeSpan.FromMinutes(_xpConfig.Data.MessageXpCooldown), TimeSpan.FromMinutes(_xpConfig.Data.MessageXpCooldown),

View File

@@ -3,7 +3,7 @@ using NadekoBot.Modules.Xp.Services;
namespace NadekoBot.Modules.Xp; namespace NadekoBot.Modules.Xp;
public readonly struct LevelStats public class LevelStats
{ {
public long Level { get; } public long Level { get; }
public long LevelXp { get; } public long LevelXp { get; }