diff --git a/src/NadekoBot/Modules/Gambling/CurrencyEventsCommands.cs b/src/NadekoBot/Modules/Gambling/CurrencyEventsCommands.cs index a250a80d..6fbee42e 100644 --- a/src/NadekoBot/Modules/Gambling/CurrencyEventsCommands.cs +++ b/src/NadekoBot/Modules/Gambling/CurrencyEventsCommands.cs @@ -11,6 +11,8 @@ using NadekoBot.Common; using NadekoBot.Common.Attributes; using NadekoBot.Common.Collections; using NLog; +using System.Collections.Concurrent; +using System.Collections.Generic; namespace NadekoBot.Modules.Gambling { @@ -137,14 +139,14 @@ namespace NadekoBot.Modules.Gambling desc, footer: footer) .ConfigureAwait(false); - await new FlowerReactionEvent(_client, _cs).Start(msg, context, amount); + await new FlowerReactionEvent(_client, _cs, amount).Start(msg, context); } } } public abstract class CurrencyEvent { - public abstract Task Start(IUserMessage msg, ICommandContext channel, int amount); + public abstract Task Start(IUserMessage msg, ICommandContext channel); } public class FlowerReactionEvent : CurrencyEvent @@ -160,14 +162,39 @@ namespace NadekoBot.Modules.Gambling private CancellationTokenSource Source { get; } private CancellationToken CancelToken { get; } - public FlowerReactionEvent(DiscordSocketClient client, CurrencyService cs) + private readonly ConcurrentQueue _toGiveTo = new ConcurrentQueue(); + private readonly int _amount; + + public FlowerReactionEvent(DiscordSocketClient client, CurrencyService cs, int amount) { _log = LogManager.GetCurrentClassLogger(); _client = client; _cs = cs; _botUser = client.CurrentUser; + _amount = amount; Source = new CancellationTokenSource(); CancelToken = Source.Token; + + var _ = Task.Run(async () => + { + + var users = new List(); + while (!CancelToken.IsCancellationRequested) + { + await Task.Delay(1000).ConfigureAwait(false); + while (_toGiveTo.TryDequeue(out var usrId)) + { + users.Add(usrId); + } + + if (users.Count > 0) + { + await _cs.AddToManyAsync("", _amount, users.ToArray()).ConfigureAwait(false); + } + + users.Clear(); + } + }, CancelToken); } private async Task End() @@ -191,7 +218,7 @@ namespace NadekoBot.Modules.Gambling return Task.CompletedTask; } - public override async Task Start(IUserMessage umsg, ICommandContext context, int amount) + public override async Task Start(IUserMessage umsg, ICommandContext context) { StartingMessage = umsg; _client.MessageDeleted += MessageDeletedEventHandler; @@ -206,7 +233,7 @@ namespace NadekoBot.Modules.Gambling catch { return; } } } - using (StartingMessage.OnReaction(_client, async (r) => + using (StartingMessage.OnReaction(_client, (r) => { try { @@ -215,8 +242,7 @@ namespace NadekoBot.Modules.Gambling if (r.Emote.Name == "🌸" && r.User.IsSpecified && ((DateTime.UtcNow - r.User.Value.CreatedAt).TotalDays > 5) && _flowerReactionAwardedUsers.Add(r.User.Value.Id)) { - await _cs.AddAsync(r.User.Value, "Flower Reaction Event", amount, false) - .ConfigureAwait(false); + _toGiveTo.Enqueue(r.UserId); } } catch diff --git a/src/NadekoBot/Services/CurrencyService.cs b/src/NadekoBot/Services/CurrencyService.cs index d7306a81..5b8fb44f 100644 --- a/src/NadekoBot/Services/CurrencyService.cs +++ b/src/NadekoBot/Services/CurrencyService.cs @@ -4,6 +4,7 @@ using Discord; using NadekoBot.Extensions; using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database; +using NadekoBot.Services; namespace NadekoBot.Services { @@ -60,6 +61,26 @@ namespace NadekoBot.Services return true; } + public async Task AddToManyAsync(string reason, long amount, params ulong[] userIds) + { + using (var uow = _db.UnitOfWork) + { + foreach (var userId in userIds) + { + var transaction = new CurrencyTransaction() + { + UserId = userId, + Reason = reason, + Amount = amount, + }; + uow.Currency.TryUpdateState(userId, amount); + uow.CurrencyTransactions.Add(transaction); + } + + await uow.CompleteAsync(); + } + } + public async Task AddAsync(IUser author, string reason, long amount, bool sendMessage) { await AddAsync(author.Id, reason, amount); diff --git a/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs b/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs index 4903fd66..3c3aabf9 100644 --- a/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs +++ b/src/NadekoBot/Services/Discord/SocketMessageEventWrapper.cs @@ -24,36 +24,45 @@ namespace NadekoBot.Services.Discord private Task Discord_ReactionsCleared(Cacheable msg, ISocketMessageChannel channel) { - try + Task.Run(() => { - if (msg.Id == Message.Id) - OnReactionsCleared?.Invoke(); - } - catch { } + try + { + if (msg.Id == Message.Id) + OnReactionsCleared?.Invoke(); + } + catch { } + }); return Task.CompletedTask; } private Task Discord_ReactionRemoved(Cacheable msg, ISocketMessageChannel channel, SocketReaction reaction) { - try + Task.Run(() => { - if (msg.Id == Message.Id) - OnReactionRemoved?.Invoke(reaction); - } - catch { } + try + { + if (msg.Id == Message.Id) + OnReactionRemoved?.Invoke(reaction); + } + catch { } + }); return Task.CompletedTask; } private Task Discord_ReactionAdded(Cacheable msg, ISocketMessageChannel channel, SocketReaction reaction) { - try + Task.Run(() => { - if (msg.Id == Message.Id) - OnReactionAdded?.Invoke(reaction); - } - catch { } + try + { + if (msg.Id == Message.Id) + OnReactionAdded?.Invoke(reaction); + } + catch { } + }); return Task.CompletedTask; }