Added an option to award currency based on received xp

This commit is contained in:
Kwoth
2022-08-26 13:41:30 +02:00
parent bed36f8784
commit 9eae27bc15
6 changed files with 63 additions and 39 deletions

View File

@@ -26,6 +26,9 @@ public sealed partial class XpConfig : ICloneable<XpConfig>
[Comment(@"The maximum amount of minutes the bot will keep track of a user in a voice channel")] [Comment(@"The maximum amount of minutes the bot will keep track of a user in a voice channel")]
public int VoiceMaxMinutes { get; set; } = 720; public int VoiceMaxMinutes { get; set; } = 720;
[Comment(@"The amount of currency users will receive for each point of global xp that they earn")]
public float CurrencyPerXp { get; set; } = 0;
[Comment(@"Xp Shop config")] [Comment(@"Xp Shop config")]
public ShopConfig Shop { get; set; } = new(); public ShopConfig Shop { get; set; } = new();

View File

@@ -52,11 +52,11 @@ public sealed class XpConfigService : ConfigServiceBase<XpConfig>
}); });
} }
if (data.Version < 5) if (data.Version < 6)
{ {
ModifyConfig(c => ModifyConfig(c =>
{ {
c.Version = 5; c.Version = 6;
}); });
} }
} }

View File

@@ -176,6 +176,16 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
var gxps = new List<UserXpStats>(globalToAdd.Count); var gxps = new List<UserXpStats>(globalToAdd.Count);
await using (var ctx = _db.GetDbContext()) await using (var ctx = _db.GetDbContext())
{ {
var conf = _xpConfig.Data;
if (conf.CurrencyPerXp > 0)
{
foreach (var user in globalToAdd)
{
var amount = user.Value.XpAmount * conf.CurrencyPerXp;
await _cs.AddAsync(user.Key, (long)(amount), null);
}
}
// update global user xp in batches // update global user xp in batches
// group by xp amount and update the same amounts at the same time // group by xp amount and update the same amounts at the same time
foreach (var group in globalToAdd.GroupBy(x => x.Value.XpAmount, x => x.Key)) foreach (var group in globalToAdd.GroupBy(x => x.Value.XpAmount, x => x.Key))
@@ -197,7 +207,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
dus.AddRange(items); dus.AddRange(items);
} }
// update guild user xp in batches // update guild user xp in batches
foreach (var (guildId, toAdd) in guildToAdd) foreach (var (guildId, toAdd) in guildToAdd)
{ {

View File

@@ -27,7 +27,7 @@ public class DefaultWallet : IWallet
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
public async Task<bool> Take(long amount, TxData txData) public async Task<bool> Take(long amount, TxData? txData)
{ {
if (amount < 0) if (amount < 0)
throw new ArgumentOutOfRangeException(nameof(amount), "Amount to take must be non negative."); throw new ArgumentOutOfRangeException(nameof(amount), "Amount to take must be non negative.");
@@ -44,24 +44,27 @@ public class DefaultWallet : IWallet
if (changed == 0) if (changed == 0)
return false; return false;
await ctx if (txData is not null)
.GetTable<CurrencyTransaction>() {
.InsertAsync(() => new() await ctx
{ .GetTable<CurrencyTransaction>()
Amount = -amount, .InsertAsync(() => new()
Note = txData.Note, {
UserId = userId, Amount = -amount,
Type = txData.Type, Note = txData.Note,
Extra = txData.Extra, UserId = userId,
OtherId = txData.OtherId, Type = txData.Type,
DateAdded = DateTime.UtcNow Extra = txData.Extra,
}); OtherId = txData.OtherId,
DateAdded = DateTime.UtcNow
});
}
return true; return true;
} }
public async Task Add(long amount, TxData txData) public async Task Add(long amount, TxData? txData)
{ {
if (amount <= 0) if (amount <= 0)
throw new ArgumentOutOfRangeException(nameof(amount), "Amount must be greater than 0."); throw new ArgumentOutOfRangeException(nameof(amount), "Amount must be greater than 0.");
@@ -92,16 +95,19 @@ public class DefaultWallet : IWallet
await tran.CommitAsync(); await tran.CommitAsync();
} }
await ctx.GetTable<CurrencyTransaction>() if (txData is not null)
.InsertAsync(() => new() {
{ await ctx.GetTable<CurrencyTransaction>()
Amount = amount, .InsertAsync(() => new()
UserId = userId, {
Note = txData.Note, Amount = amount,
Type = txData.Type, UserId = userId,
Extra = txData.Extra, Note = txData.Note,
OtherId = txData.OtherId, Type = txData.Type,
DateAdded = DateTime.UtcNow Extra = txData.Extra,
}); OtherId = txData.OtherId,
DateAdded = DateTime.UtcNow
});
}
} }
} }

View File

@@ -5,31 +5,35 @@ public interface IWallet
public ulong UserId { get; } public ulong UserId { get; }
public Task<long> GetBalance(); public Task<long> GetBalance();
public Task<bool> Take(long amount, TxData txData); public Task<bool> Take(long amount, TxData? txData);
public Task Add(long amount, TxData txData); public Task Add(long amount, TxData? txData);
public async Task<bool> Transfer( public async Task<bool> Transfer(
long amount, long amount,
IWallet to, IWallet to,
TxData txData) TxData? txData)
{ {
if (amount <= 0) if (amount <= 0)
throw new ArgumentOutOfRangeException(nameof(amount), "Amount must be greater than 0."); throw new ArgumentOutOfRangeException(nameof(amount), "Amount must be greater than 0.");
var succ = await Take(amount, if (txData is not null)
txData with txData = txData with
{ {
OtherId = to.UserId OtherId = to.UserId
}); };
var succ = await Take(amount, txData);
if (!succ) if (!succ)
return false; return false;
await to.Add(amount, if (txData is not null)
txData with txData = txData with
{ {
OtherId = UserId OtherId = UserId
}); };
await to.Add(amount, txData);
return true; return true;
} }

View File

@@ -1,5 +1,5 @@
# DO NOT CHANGE # DO NOT CHANGE
version: 5 version: 6
# How much XP will the users receive per message # How much XP will the users receive per message
xpPerMessage: 3 xpPerMessage: 3
# How often can the users receive XP in minutes # How often can the users receive XP in minutes
@@ -10,6 +10,8 @@ xpFromImage: 0
voiceXpPerMinute: 0 voiceXpPerMinute: 0
# The maximum amount of minutes the bot will keep track of a user in a voice channel # The maximum amount of minutes the bot will keep track of a user in a voice channel
voiceMaxMinutes: 720 voiceMaxMinutes: 720
# The amount of currency users will receive for each point of global xp that they earn
currencyPerXp: 0
# Xp Shop config # Xp Shop config
shop: shop:
# Whether the xp shop is enabled # Whether the xp shop is enabled