From eecccc8100a1bcbb8c4d13c5f6a4ae0f867a2bc9 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Wed, 2 Feb 2022 13:52:54 +0100 Subject: [PATCH] - Added currency.transactionsLifetime which controls auto-deletion of currency transactions from the database - Updated changelog --- CHANGELOG.md | 1 + src/NadekoBot/Modules/Gambling/Gambling.cs | 1 - .../Modules/Gambling/GamblingConfig.cs | 4 + .../Modules/Gambling/GamblingService.cs | 81 ++++++++++++++----- .../Modules/Gambling/Waifus/WaifuService.cs | 1 - src/NadekoBot/data/gambling.yml | 3 + 6 files changed, 70 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a8974dbc..e30b63d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog. - waifu.decay.percent - How much % to subtract from unclaimed waifu - waifu.decay.hourInterval - How often to decay the price - waifu.decay.minPrice - Unclaimed waifus with price lower than the one specified here will not be affected by the decay +- Added `currency.transactionsLifetime` to `data/gambling.yml` Any transaction older than the number of days specified will be automatically deleted ### Fixed - Fixed an extra whitespace in usage part of command help if the command has no arguments diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index d9d956947..fd401dfbd 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -206,7 +206,6 @@ public partial class Gambling : GamblingModule public partial Task CurrencyTransactions(IUser usr, int page) => InternalCurrencyTransactions(usr.Id, page); - // todo curtrs max lifetime private async Task InternalCurrencyTransactions(ulong userId, int page) { if (--page < 0) diff --git a/src/NadekoBot/Modules/Gambling/GamblingConfig.cs b/src/NadekoBot/Modules/Gambling/GamblingConfig.cs index bcef8d65c..46bd69b51 100644 --- a/src/NadekoBot/Modules/Gambling/GamblingConfig.cs +++ b/src/NadekoBot/Modules/Gambling/GamblingConfig.cs @@ -77,6 +77,10 @@ public class CurrencyConfig [Comment(@"What is the name of the currency")] public string Name { get; set; } = "Nadeko Flower"; + + [Comment(@"For how long will the transactions be kept in the database (curtrs) +Set 0 to disable cleanup (keep transactions forever)")] + public int TransactionsLifetime { get; set; } = 0; } [Cloneable] diff --git a/src/NadekoBot/Modules/Gambling/GamblingService.cs b/src/NadekoBot/Modules/Gambling/GamblingService.cs index 19e309768..bb27d4392 100644 --- a/src/NadekoBot/Modules/Gambling/GamblingService.cs +++ b/src/NadekoBot/Modules/Gambling/GamblingService.cs @@ -1,4 +1,5 @@ #nullable disable +using LinqToDB; using Microsoft.EntityFrameworkCore; using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Db; @@ -37,7 +38,40 @@ public class GamblingService : INService, IReadyExecutor _gss = gss; } - public async Task OnReadyAsync() + public Task OnReadyAsync() + => Task.WhenAll(CurrencyDecayLoopAsync(), TransactionClearLoopAsync()); + + private async Task TransactionClearLoopAsync() + { + if (_bot.Client.ShardId != 0) + return; + + using var timer = new PeriodicTimer(TimeSpan.FromHours(1)); + while (await timer.WaitForNextTickAsync()) + { + try + { + var lifetime = _gss.Data.Currency.TransactionsLifetime; + if (lifetime <= 0) + continue; + + var now = DateTime.UtcNow; + var days = TimeSpan.FromDays(lifetime); + await using var uow = _db.GetDbContext(); + await uow.CurrencyTransactions + .DeleteAsync(ct => ct.DateAdded == null || now - ct.DateAdded < days); + await uow.SaveChangesAsync(); + } + catch (Exception ex) + { + Log.Warning(ex, + "An unexpected error occurred in transactions cleanup loop: {ErrorMessage}", + ex.Message); + } + } + } + + private async Task CurrencyDecayLoopAsync() { if (_bot.Client.ShardId != 0) return; @@ -45,28 +79,30 @@ public class GamblingService : INService, IReadyExecutor using var timer = new PeriodicTimer(TimeSpan.FromMinutes(5)); while (await timer.WaitForNextTickAsync()) { - var config = _gss.Data; - var maxDecay = config.Decay.MaxDecay; - if (config.Decay.Percent is <= 0 or > 1 || maxDecay < 0) - continue; + try + { + var config = _gss.Data; + var maxDecay = config.Decay.MaxDecay; + if (config.Decay.Percent is <= 0 or > 1 || maxDecay < 0) + continue; - await using var uow = _db.GetDbContext(); - var lastCurrencyDecay = _cache.GetLastCurrencyDecay(); + await using var uow = _db.GetDbContext(); + var lastCurrencyDecay = _cache.GetLastCurrencyDecay(); - if (DateTime.UtcNow - lastCurrencyDecay < TimeSpan.FromHours(config.Decay.HourInterval)) - continue; + if (DateTime.UtcNow - lastCurrencyDecay < TimeSpan.FromHours(config.Decay.HourInterval)) + continue; - Log.Information(@"Decaying users' currency - decay: {ConfigDecayPercent}% + Log.Information(@"Decaying users' currency - decay: {ConfigDecayPercent}% | max: {MaxDecay} | threshold: {DecayMinTreshold}", - config.Decay.Percent * 100, - maxDecay, - config.Decay.MinThreshold); + config.Decay.Percent * 100, + maxDecay, + config.Decay.MinThreshold); - if (maxDecay == 0) - maxDecay = int.MaxValue; + if (maxDecay == 0) + maxDecay = int.MaxValue; - await uow.Database.ExecuteSqlInterpolatedAsync($@" + await uow.Database.ExecuteSqlInterpolatedAsync($@" UPDATE DiscordUser SET CurrencyAmount= CASE WHEN @@ -78,11 +114,18 @@ SET CurrencyAmount= END WHERE CurrencyAmount > {config.Decay.MinThreshold} AND UserId!={_client.CurrentUser.Id};"); - _cache.SetLastCurrencyDecay(); - await uow.SaveChangesAsync(); + _cache.SetLastCurrencyDecay(); + await uow.SaveChangesAsync(); + } + catch (Exception ex) + { + Log.Warning(ex, + "An unexpected error occurred in currency decay loop: {ErrorMessage}", + ex.Message); + } } } - + public async Task SlotAsync(ulong userId, long amount) { var takeRes = await _cs.RemoveAsync(userId, amount, new("slot", "bet")); diff --git a/src/NadekoBot/Modules/Gambling/Waifus/WaifuService.cs b/src/NadekoBot/Modules/Gambling/Waifus/WaifuService.cs index c0a49a08a..6391976f1 100644 --- a/src/NadekoBot/Modules/Gambling/Waifus/WaifuService.cs +++ b/src/NadekoBot/Modules/Gambling/Waifus/WaifuService.cs @@ -10,7 +10,6 @@ using NadekoBot.Services.Database.Models; namespace NadekoBot.Modules.Gambling.Services; -// todo waifu price int public class WaifuService : INService, IReadyExecutor { private readonly DbService _db; diff --git a/src/NadekoBot/data/gambling.yml b/src/NadekoBot/data/gambling.yml index 2e9aa2e39..35995d741 100644 --- a/src/NadekoBot/data/gambling.yml +++ b/src/NadekoBot/data/gambling.yml @@ -6,6 +6,9 @@ currency: sign: "🌸" # What is the name of the currency name: Nadeko Flower + # For how long will the transactions be kept in the database (curtrs) + # Set 0 to disable cleanup (keep transactions forever) + transactionsLifetime: 0 # Minimum amount users can bet (>=0) minBet: 0 # Maximum amount users can bet