mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 01:38:27 -04:00
Revert "Fixed .crypto - some extra fields which were causing deserialization issues"
This reverts commit f65ba100af
.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
@@ -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);
|
||||||
|
@@ -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; }
|
||||||
}
|
}
|
@@ -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
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
var xp = item.Sum(x => x.XpAmount);
|
||||||
// .UpdateWithOutputAsync(old => new()
|
|
||||||
// {
|
|
||||||
// Xp = old.Xp + item.XpAmount
|
|
||||||
// }, (o, n) => n);
|
|
||||||
|
|
||||||
var user = item.User;
|
var usr = uow.GetOrCreateUserXpStats(item.Key.GuildId, item.Key.User.Id);
|
||||||
var du = await ctx.GetTable<DiscordUser>()
|
var du = uow.GetOrCreateUser(item.Key.User);
|
||||||
.Where(x => x.UserId == user.Id)
|
|
||||||
.UpdateWithOutputAsync(
|
var globalXp = du.TotalXp;
|
||||||
old => new()
|
var oldGlobalLevelData = new LevelStats(globalXp);
|
||||||
{
|
var newGlobalLevelData = new LevelStats(globalXp + xp);
|
||||||
TotalXp = old.TotalXp + item.XpAmount
|
|
||||||
},
|
var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
|
||||||
(_, n) => n);
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
//give role
|
||||||
|
if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
|
||||||
|
{
|
||||||
|
rrews = uow.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
|
||||||
|
roleRewards.Add(usr.GuildId, rrews);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!curRewards.TryGetValue(usr.GuildId, out var crews))
|
||||||
|
{
|
||||||
|
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 tran.CommitAsync();
|
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;
|
||||||
|
|
||||||
var users = await ctx.GetTable<DiscordUser>()
|
await chan.SendConfirmAsync(_eb,
|
||||||
.Where(x => userAdds.Keys.Contains(x.UserId))
|
_strings.GetText(strs.level_up_global(x.User.Mention,
|
||||||
.ToListAsyncLinqToDB();
|
Format.Bold(x.Level.ToString())),
|
||||||
|
x.Guild.Id));
|
||||||
// foreach (var user in users)
|
}
|
||||||
// {
|
})
|
||||||
// var oldLevel = new LevelStats(user.TotalXp - userAdds[user.UserId]);
|
.WhenAll();
|
||||||
// var newLevel = new LevelStats(user.TotalXp);
|
|
||||||
//
|
|
||||||
// if (oldLevel.Level != newLevel.Level)
|
|
||||||
// {
|
|
||||||
// await _levelUpQueue.EnqueueAsync(
|
|
||||||
// NotifyUser(user.UserId,
|
|
||||||
// user.NotifyOnLevelUp));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return;
|
|
||||||
// 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>>();
|
|
||||||
//
|
|
||||||
// var toAddTo = new List<UserCacheItem>();
|
|
||||||
// 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;
|
|
||||||
//
|
|
||||||
// await using (var uow = _db.GetDbContext())
|
|
||||||
// {
|
|
||||||
// foreach (var item in group)
|
|
||||||
// {
|
|
||||||
// var xp = item.Sum(x => x.XpAmount);
|
|
||||||
//
|
|
||||||
// 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));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// 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));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //give role
|
|
||||||
// if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
|
|
||||||
// {
|
|
||||||
// rrews = uow.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
|
|
||||||
// roleRewards.Add(usr.GuildId, rrews);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (!curRewards.TryGetValue(usr.GuildId, out var crews))
|
|
||||||
// {
|
|
||||||
// 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),
|
||||||
|
@@ -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; }
|
||||||
|
Reference in New Issue
Block a user