using Discord; using Discord.Commands; using Discord.WebSocket; using NadekoBot.Common; using NadekoBot.Common.Collections; using NadekoBot.Core.Services; using System; using System.Linq; using System.Threading.Tasks; namespace NadekoBot.Modules.Gambling.Common.CurrencyEvents { public class SneakyEvent : CurrencyEvent { public event Action OnEnded; public string Code { get; private set; } = string.Empty; private readonly ConcurrentHashSet _sneakyGameAwardedUsers = new ConcurrentHashSet(); private readonly char[] _sneakyGameStatusChars = Enumerable.Range(48, 10) .Concat(Enumerable.Range(65, 26)) .Concat(Enumerable.Range(97, 26)) .Select(x => (char)x) .ToArray(); private readonly CurrencyService _cs; private readonly DiscordSocketClient _client; private readonly IBotConfigProvider _bc; private readonly int _length; public SneakyEvent(CurrencyService cs, DiscordSocketClient client, IBotConfigProvider bc, int len) { _cs = cs; _client = client; _bc = bc; _length = len; } public override async Task Start(IUserMessage msg, ICommandContext channel) { GenerateCode(); //start the event _client.MessageReceived += SneakyGameMessageReceivedEventHandler; await _client.SetGameAsync($"type {Code} for " + _bc.BotConfig.CurrencyPluralName) .ConfigureAwait(false); await Task.Delay(_length * 1000).ConfigureAwait(false); await Stop().ConfigureAwait(false); } private void GenerateCode() { var rng = new NadekoRandom(); for (var i = 0; i < 5; i++) { Code += _sneakyGameStatusChars[rng.Next(0, _sneakyGameStatusChars.Length)]; } } public override async Task Stop() { try { _client.MessageReceived -= SneakyGameMessageReceivedEventHandler; Code = string.Empty; _sneakyGameAwardedUsers.Clear(); await _client.SetGameAsync(null).ConfigureAwait(false); } catch { } finally { OnEnded?.Invoke(); } } private Task SneakyGameMessageReceivedEventHandler(SocketMessage arg) { if (arg.Content == Code && _sneakyGameAwardedUsers.Add(arg.Author.Id)) { var _ = Task.Run(async () => { await _cs.AddAsync(arg.Author, "Sneaky Game Event", 100, false) .ConfigureAwait(false); try { await arg.DeleteAsync(new RequestOptions() { RetryMode = RetryMode.AlwaysFail }).ConfigureAwait(false); } catch { // ignored } }); } return Task.CompletedTask; } } }