Added .betstats command, shows statistics for multiple gambling commands, .slotstats removed as it is obsolete

This commit is contained in:
Kwoth
2022-10-03 13:49:52 +02:00
parent 9ffa701742
commit df3909fc55
13 changed files with 3145 additions and 50 deletions

View File

@@ -4,12 +4,16 @@ using NadekoBot.Services.Currency;
namespace NadekoBot.Services;
public class CurrencyService : ICurrencyService, INService
public sealed class CurrencyService : ICurrencyService, INService
{
private readonly DbService _db;
private readonly ITxTracker _txTracker;
public CurrencyService(DbService db)
=> _db = db;
public CurrencyService(DbService db, ITxTracker txTracker)
{
_db = db;
_txTracker = txTracker;
}
public Task<IWallet> GetWalletAsync(ulong userId, CurrencyType type = CurrencyType.Default)
{
@@ -32,7 +36,7 @@ public class CurrencyService : ICurrencyService, INService
var wallet = await GetWalletAsync(userId);
await wallet.Add(amount, txData);
}
return;
}
@@ -49,13 +53,13 @@ public class CurrencyService : ICurrencyService, INService
{
await using var ctx = _db.GetDbContext();
await ctx.DiscordUser
.Where(x => userIds.Contains(x.UserId))
.UpdateAsync(du => new()
{
CurrencyAmount = du.CurrencyAmount >= amount
? du.CurrencyAmount - amount
: 0
});
.Where(x => userIds.Contains(x.UserId))
.UpdateAsync(du => new()
{
CurrencyAmount = du.CurrencyAmount >= amount
? du.CurrencyAmount - amount
: 0
});
await ctx.SaveChangesAsync();
return;
}
@@ -70,16 +74,14 @@ public class CurrencyService : ICurrencyService, INService
{
var wallet = await GetWalletAsync(userId);
await wallet.Add(amount, txData);
await _txTracker.TrackAdd(amount, txData);
}
public async Task AddAsync(
IUser user,
long amount,
TxData txData)
{
var wallet = await GetWalletAsync(user.Id);
await wallet.Add(amount, txData);
}
=> await AddAsync(user.Id, amount, txData);
public async Task<bool> RemoveAsync(
ulong userId,
@@ -87,15 +89,14 @@ public class CurrencyService : ICurrencyService, INService
TxData txData)
{
var wallet = await GetWalletAsync(userId);
return await wallet.Take(amount, txData);
var result = await wallet.Take(amount, txData);
await _txTracker.TrackRemove(amount, txData);
return result;
}
public async Task<bool> RemoveAsync(
IUser user,
long amount,
TxData txData)
{
var wallet = await GetWalletAsync(user.Id);
return await wallet.Take(amount, txData);
}
=> await RemoveAsync(user.Id, amount, txData);
}

View File

@@ -0,0 +1,105 @@
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Services.Currency;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Services;
public sealed class GamblingTxTracker : ITxTracker, INService, IReadyExecutor
{
private static readonly IReadOnlySet<string> _gamblingTypes = new HashSet<string>(new[]
{
"lula",
"betroll",
"betflip",
"blackjack",
"betdraw",
"slot",
});
private ConcurrentDictionary<string, (decimal Bet, decimal PaidOut)> _stats = new();
private readonly DbService _db;
public GamblingTxTracker(DbService db)
{
_db = db;
}
public async Task OnReadyAsync()
{
using var timer = new PeriodicTimer(TimeSpan.FromHours(1));
while (await timer.WaitForNextTickAsync())
{
await using var ctx = _db.GetDbContext();
await using var trans = await ctx.Database.BeginTransactionAsync();
try
{
var keys = _stats.Keys;
foreach (var key in keys)
{
if (_stats.TryRemove(key, out var stat))
{
await ctx.GetTable<GamblingStats>()
.InsertOrUpdateAsync(() => new()
{
Feature = key,
Bet = stat.Bet,
PaidOut = stat.PaidOut,
DateAdded = DateTime.UtcNow
}, old => new()
{
Bet = old.Bet + stat.Bet,
PaidOut = old.PaidOut + stat.PaidOut,
}, () => new()
{
Feature = key
});
}
}
}
catch (Exception ex)
{
Log.Error(ex, "An error occurred in gambling tx tracker");
}
finally
{
await trans.CommitAsync();
}
}
}
public Task TrackAdd(long amount, TxData txData)
{
if (_gamblingTypes.Contains(txData.Type))
{
_stats.AddOrUpdate(txData.Type,
_ => (0, amount),
(_, old) => (old.Bet, old.PaidOut + amount));
}
return Task.CompletedTask;
}
public Task TrackRemove(long amount, TxData txData)
{
if (_gamblingTypes.Contains(txData.Type))
{
_stats.AddOrUpdate(txData.Type,
_ => (amount, 0),
(_, old) => (old.Bet + amount, old.PaidOut));
}
return Task.CompletedTask;
}
public async Task<IReadOnlyCollection<GamblingStats>> GetAllAsync()
{
await using var ctx = _db.GetDbContext();
return await ctx
.GetTable<GamblingStats>()
.ToListAsync();
}
}

View File

@@ -0,0 +1,9 @@
using NadekoBot.Services.Currency;
namespace NadekoBot.Services;
public interface ITxTracker
{
Task TrackAdd(long amount, TxData txData);
Task TrackRemove(long amount, TxData txData);
}