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")]
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")]
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 =>
{
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);
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
// 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))
@@ -197,7 +207,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
dus.AddRange(items);
}
// update guild user xp in batches
foreach (var (guildId, toAdd) in guildToAdd)
{

View File

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

View File

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

View File

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