2017-01-15 14:09:48 +00:00
|
|
|
|
using Discord;
|
|
|
|
|
using Discord.Commands;
|
|
|
|
|
using NadekoBot.Extensions;
|
|
|
|
|
using NadekoBot.Services;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
2017-01-30 05:26:47 +00:00
|
|
|
|
using Discord.WebSocket;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
using System.Threading;
|
2017-07-17 19:42:36 +00:00
|
|
|
|
using NadekoBot.Common;
|
|
|
|
|
using NadekoBot.Common.Attributes;
|
|
|
|
|
using NadekoBot.Common.Collections;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
using NLog;
|
2017-08-14 03:19:37 +00:00
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
2017-09-17 23:41:43 +00:00
|
|
|
|
using NadekoBot.Services.Database.Models;
|
2017-01-15 14:09:48 +00:00
|
|
|
|
|
|
|
|
|
namespace NadekoBot.Modules.Gambling
|
|
|
|
|
{
|
2017-10-04 22:51:12 +00:00
|
|
|
|
//todo mess, needs unload thing too - refactor
|
2017-01-15 14:09:48 +00:00
|
|
|
|
public partial class Gambling
|
|
|
|
|
{
|
|
|
|
|
[Group]
|
2017-07-17 19:42:36 +00:00
|
|
|
|
public class CurrencyEventsCommands : NadekoSubmodule
|
2017-01-15 14:09:48 +00:00
|
|
|
|
{
|
|
|
|
|
public enum CurrencyEvent
|
|
|
|
|
{
|
2017-09-17 23:41:43 +00:00
|
|
|
|
Reaction,
|
2017-01-30 05:26:47 +00:00
|
|
|
|
SneakyGameStatus
|
2017-01-15 14:09:48 +00:00
|
|
|
|
}
|
|
|
|
|
//flower reaction event
|
2017-02-15 10:41:32 +00:00
|
|
|
|
private static readonly ConcurrentHashSet<ulong> _sneakyGameAwardedUsers = new ConcurrentHashSet<ulong>();
|
2017-05-24 20:28:16 +00:00
|
|
|
|
|
2017-01-30 05:26:47 +00:00
|
|
|
|
private static readonly char[] _sneakyGameStatusChars = Enumerable.Range(48, 10)
|
|
|
|
|
.Concat(Enumerable.Range(65, 26))
|
|
|
|
|
.Concat(Enumerable.Range(97, 26))
|
|
|
|
|
.Select(x => (char)x)
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
2017-05-24 20:28:16 +00:00
|
|
|
|
private string _secretCode = string.Empty;
|
2017-06-19 13:42:10 +00:00
|
|
|
|
private readonly DiscordSocketClient _client;
|
2017-07-20 03:10:39 +00:00
|
|
|
|
private readonly IBotConfigProvider _bc;
|
2017-05-29 04:13:22 +00:00
|
|
|
|
private readonly CurrencyService _cs;
|
2017-05-24 20:28:16 +00:00
|
|
|
|
|
2017-07-20 03:10:39 +00:00
|
|
|
|
public CurrencyEventsCommands(DiscordSocketClient client, IBotConfigProvider bc, CurrencyService cs)
|
2017-05-24 20:28:16 +00:00
|
|
|
|
{
|
|
|
|
|
_client = client;
|
|
|
|
|
_bc = bc;
|
2017-05-29 04:13:22 +00:00
|
|
|
|
_cs = cs;
|
2017-05-24 20:28:16 +00:00
|
|
|
|
}
|
2017-01-30 05:26:47 +00:00
|
|
|
|
|
2017-01-15 14:09:48 +00:00
|
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
|
|
|
|
[RequireContext(ContextType.Guild)]
|
|
|
|
|
[OwnerOnly]
|
2017-01-30 05:26:47 +00:00
|
|
|
|
public async Task StartEvent(CurrencyEvent e, int arg = -1)
|
2017-01-15 14:09:48 +00:00
|
|
|
|
{
|
2017-02-14 13:30:21 +00:00
|
|
|
|
switch (e)
|
2017-01-15 14:09:48 +00:00
|
|
|
|
{
|
2017-09-17 23:41:43 +00:00
|
|
|
|
case CurrencyEvent.Reaction:
|
2017-09-18 07:24:42 +00:00
|
|
|
|
await ReactionEvent(Context, arg).ConfigureAwait(false);
|
2017-02-14 13:30:21 +00:00
|
|
|
|
break;
|
|
|
|
|
case CurrencyEvent.SneakyGameStatus:
|
|
|
|
|
await SneakyGameStatusEvent(Context, arg).ConfigureAwait(false);
|
|
|
|
|
break;
|
2017-01-15 14:09:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-15 00:54:19 +00:00
|
|
|
|
public async Task SneakyGameStatusEvent(ICommandContext context, int? arg)
|
2017-01-30 05:26:47 +00:00
|
|
|
|
{
|
|
|
|
|
int num;
|
|
|
|
|
if (arg == null || arg < 5)
|
|
|
|
|
num = 60;
|
|
|
|
|
else
|
|
|
|
|
num = arg.Value;
|
|
|
|
|
|
2017-02-15 10:41:32 +00:00
|
|
|
|
if (_secretCode != string.Empty)
|
2017-01-30 05:26:47 +00:00
|
|
|
|
return;
|
|
|
|
|
var rng = new NadekoRandom();
|
|
|
|
|
|
2017-02-15 10:41:32 +00:00
|
|
|
|
for (var i = 0; i < 5; i++)
|
2017-01-30 05:26:47 +00:00
|
|
|
|
{
|
|
|
|
|
_secretCode += _sneakyGameStatusChars[rng.Next(0, _sneakyGameStatusChars.Length)];
|
|
|
|
|
}
|
2017-02-14 13:30:21 +00:00
|
|
|
|
|
2017-07-20 03:10:39 +00:00
|
|
|
|
await _client.SetGameAsync($"type {_secretCode} for " + _bc.BotConfig.CurrencyPluralName)
|
2017-01-30 05:26:47 +00:00
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-02-15 10:41:32 +00:00
|
|
|
|
var title = GetText("sneakygamestatus_title");
|
2017-07-20 03:10:39 +00:00
|
|
|
|
var desc = GetText("sneakygamestatus_desc", Format.Bold(100.ToString()) + _bc.BotConfig.CurrencySign, Format.Bold(num.ToString()));
|
2017-02-15 10:41:32 +00:00
|
|
|
|
await context.Channel.SendConfirmAsync(title, desc).ConfigureAwait(false);
|
2017-01-30 05:26:47 +00:00
|
|
|
|
}
|
2017-02-14 13:30:21 +00:00
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
// ignored
|
|
|
|
|
}
|
2017-01-30 05:26:47 +00:00
|
|
|
|
|
|
|
|
|
|
2017-05-24 20:28:16 +00:00
|
|
|
|
_client.MessageReceived += SneakyGameMessageReceivedEventHandler;
|
2017-01-30 05:26:47 +00:00
|
|
|
|
await Task.Delay(num * 1000);
|
2017-05-24 20:28:16 +00:00
|
|
|
|
_client.MessageReceived -= SneakyGameMessageReceivedEventHandler;
|
2017-01-30 05:26:47 +00:00
|
|
|
|
|
2017-02-03 10:36:58 +00:00
|
|
|
|
var cnt = _sneakyGameAwardedUsers.Count;
|
2017-01-30 05:26:47 +00:00
|
|
|
|
_sneakyGameAwardedUsers.Clear();
|
2017-02-15 10:41:32 +00:00
|
|
|
|
_secretCode = string.Empty;
|
2017-01-30 05:26:47 +00:00
|
|
|
|
|
2017-05-24 20:28:16 +00:00
|
|
|
|
await _client.SetGameAsync(GetText("sneakygamestatus_end", cnt))
|
2017-01-30 05:26:47 +00:00
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 20:28:16 +00:00
|
|
|
|
private Task SneakyGameMessageReceivedEventHandler(SocketMessage arg)
|
2017-01-30 05:26:47 +00:00
|
|
|
|
{
|
|
|
|
|
if (arg.Content == _secretCode &&
|
|
|
|
|
_sneakyGameAwardedUsers.Add(arg.Author.Id))
|
|
|
|
|
{
|
|
|
|
|
var _ = Task.Run(async () =>
|
|
|
|
|
{
|
2017-05-29 04:13:22 +00:00
|
|
|
|
await _cs.AddAsync(arg.Author, "Sneaky Game Event", 100, false)
|
2017-01-30 05:26:47 +00:00
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
try { await arg.DeleteAsync(new RequestOptions() { RetryMode = RetryMode.AlwaysFail }).ConfigureAwait(false); }
|
2017-02-14 13:30:21 +00:00
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
// ignored
|
|
|
|
|
}
|
2017-01-30 05:26:47 +00:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-15 23:55:14 +00:00
|
|
|
|
return Task.CompletedTask;
|
2017-01-30 05:26:47 +00:00
|
|
|
|
}
|
2017-01-15 14:09:48 +00:00
|
|
|
|
|
2017-09-18 07:24:42 +00:00
|
|
|
|
public async Task ReactionEvent(ICommandContext context, int amount)
|
2017-02-15 10:41:32 +00:00
|
|
|
|
{
|
2017-02-17 13:53:13 +00:00
|
|
|
|
if (amount <= 0)
|
|
|
|
|
amount = 100;
|
|
|
|
|
|
2017-09-17 23:41:43 +00:00
|
|
|
|
var title = GetText("reaction_title");
|
|
|
|
|
var desc = GetText("reaction_desc", _bc.BotConfig.CurrencySign, Format.Bold(amount.ToString()) + _bc.BotConfig.CurrencySign);
|
|
|
|
|
var footer = GetText("reaction_footer", 24);
|
2017-02-15 10:41:32 +00:00
|
|
|
|
var msg = await context.Channel.SendConfirmAsync(title,
|
|
|
|
|
desc, footer: footer)
|
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
|
2017-09-17 23:41:43 +00:00
|
|
|
|
await new ReactionEvent(_bc.BotConfig, _client, _cs, amount).Start(msg, context);
|
2017-02-15 10:41:32 +00:00
|
|
|
|
}
|
2017-02-06 11:57:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public abstract class CurrencyEvent
|
|
|
|
|
{
|
2017-08-14 03:19:37 +00:00
|
|
|
|
public abstract Task Start(IUserMessage msg, ICommandContext channel);
|
2017-02-06 11:57:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-17 23:41:43 +00:00
|
|
|
|
public class ReactionEvent : CurrencyEvent
|
2017-02-06 11:57:38 +00:00
|
|
|
|
{
|
2017-09-17 23:41:43 +00:00
|
|
|
|
private readonly ConcurrentHashSet<ulong> _reactionAwardedUsers = new ConcurrentHashSet<ulong>();
|
|
|
|
|
private readonly BotConfig _bc;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
private readonly Logger _log;
|
2017-06-19 13:42:10 +00:00
|
|
|
|
private readonly DiscordSocketClient _client;
|
2017-05-29 04:13:22 +00:00
|
|
|
|
private readonly CurrencyService _cs;
|
2017-06-26 23:01:17 +00:00
|
|
|
|
private readonly SocketSelfUser _botUser;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
|
2017-04-15 00:54:19 +00:00
|
|
|
|
private IUserMessage StartingMessage { get; set; }
|
2017-02-06 11:57:38 +00:00
|
|
|
|
|
2017-04-15 00:54:19 +00:00
|
|
|
|
private CancellationTokenSource Source { get; }
|
|
|
|
|
private CancellationToken CancelToken { get; }
|
2017-02-06 11:57:38 +00:00
|
|
|
|
|
2017-08-14 03:19:37 +00:00
|
|
|
|
private readonly ConcurrentQueue<ulong> _toGiveTo = new ConcurrentQueue<ulong>();
|
|
|
|
|
private readonly int _amount;
|
|
|
|
|
|
2017-09-17 23:41:43 +00:00
|
|
|
|
public ReactionEvent(BotConfig bc, DiscordSocketClient client, CurrencyService cs, int amount)
|
2017-02-06 11:57:38 +00:00
|
|
|
|
{
|
2017-09-17 23:41:43 +00:00
|
|
|
|
_bc = bc;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
_log = LogManager.GetCurrentClassLogger();
|
2017-05-24 20:28:16 +00:00
|
|
|
|
_client = client;
|
2017-05-29 04:13:22 +00:00
|
|
|
|
_cs = cs;
|
2017-06-26 23:01:17 +00:00
|
|
|
|
_botUser = client.CurrentUser;
|
2017-08-14 03:19:37 +00:00
|
|
|
|
_amount = amount;
|
2017-04-15 00:54:19 +00:00
|
|
|
|
Source = new CancellationTokenSource();
|
|
|
|
|
CancelToken = Source.Token;
|
2017-08-14 03:19:37 +00:00
|
|
|
|
|
|
|
|
|
var _ = Task.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var users = new List<ulong>();
|
|
|
|
|
while (!CancelToken.IsCancellationRequested)
|
|
|
|
|
{
|
|
|
|
|
await Task.Delay(1000).ConfigureAwait(false);
|
|
|
|
|
while (_toGiveTo.TryDequeue(out var usrId))
|
|
|
|
|
{
|
|
|
|
|
users.Add(usrId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (users.Count > 0)
|
|
|
|
|
{
|
2017-09-29 14:37:26 +00:00
|
|
|
|
await _cs.AddToManyAsync("Reaction Event", _amount, users.ToArray()).ConfigureAwait(false);
|
2017-08-14 03:19:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
users.Clear();
|
|
|
|
|
}
|
|
|
|
|
}, CancelToken);
|
2017-02-06 11:57:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task End()
|
|
|
|
|
{
|
2017-04-15 00:54:19 +00:00
|
|
|
|
if(StartingMessage != null)
|
|
|
|
|
await StartingMessage.DeleteAsync().ConfigureAwait(false);
|
2017-02-06 11:57:38 +00:00
|
|
|
|
|
2017-04-15 00:54:19 +00:00
|
|
|
|
if(!Source.IsCancellationRequested)
|
|
|
|
|
Source.Cancel();
|
2017-02-06 11:57:38 +00:00
|
|
|
|
|
2017-05-24 20:28:16 +00:00
|
|
|
|
_client.MessageDeleted -= MessageDeletedEventHandler;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-15 00:54:19 +00:00
|
|
|
|
private Task MessageDeletedEventHandler(Cacheable<IMessage, ulong> msg, ISocketMessageChannel channel) {
|
|
|
|
|
if (StartingMessage?.Id == msg.Id)
|
2017-01-15 14:09:48 +00:00
|
|
|
|
{
|
2017-02-06 11:57:38 +00:00
|
|
|
|
_log.Warn("Stopping flower reaction event because message is deleted.");
|
2017-02-14 13:30:21 +00:00
|
|
|
|
var __ = Task.Run(End);
|
2017-02-06 11:57:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-14 03:19:37 +00:00
|
|
|
|
public override async Task Start(IUserMessage umsg, ICommandContext context)
|
2017-02-06 11:57:38 +00:00
|
|
|
|
{
|
2017-04-15 00:54:19 +00:00
|
|
|
|
StartingMessage = umsg;
|
2017-05-24 20:28:16 +00:00
|
|
|
|
_client.MessageDeleted += MessageDeletedEventHandler;
|
2017-02-06 11:57:38 +00:00
|
|
|
|
|
2017-09-17 23:41:43 +00:00
|
|
|
|
IEmote iemote;
|
|
|
|
|
if (Emote.TryParse(_bc.CurrencySign, out var emote))
|
|
|
|
|
{
|
|
|
|
|
iemote = emote;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
iemote = new Emoji(_bc.CurrencySign);
|
|
|
|
|
try { await StartingMessage.AddReactionAsync(iemote).ConfigureAwait(false); }
|
2017-02-06 11:57:38 +00:00
|
|
|
|
catch
|
|
|
|
|
{
|
2017-09-17 23:41:43 +00:00
|
|
|
|
try { await StartingMessage.AddReactionAsync(iemote).ConfigureAwait(false); }
|
2017-01-15 17:04:22 +00:00
|
|
|
|
catch
|
|
|
|
|
{
|
2017-04-15 00:54:19 +00:00
|
|
|
|
try { await StartingMessage.DeleteAsync().ConfigureAwait(false); }
|
2017-02-06 11:57:38 +00:00
|
|
|
|
catch { return; }
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-08-14 03:19:37 +00:00
|
|
|
|
using (StartingMessage.OnReaction(_client, (r) =>
|
2017-02-06 11:57:38 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-06-26 23:01:17 +00:00
|
|
|
|
if (r.UserId == _botUser.Id)
|
|
|
|
|
return;
|
|
|
|
|
|
2017-09-17 23:41:43 +00:00
|
|
|
|
if (r.Emote.Name == iemote.Name && r.User.IsSpecified && ((DateTime.UtcNow - r.User.Value.CreatedAt).TotalDays > 5) && _reactionAwardedUsers.Add(r.User.Value.Id))
|
2017-01-15 17:04:22 +00:00
|
|
|
|
{
|
2017-08-14 03:19:37 +00:00
|
|
|
|
_toGiveTo.Enqueue(r.UserId);
|
2017-01-15 17:04:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-14 13:30:21 +00:00
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
// ignored
|
|
|
|
|
}
|
2017-02-06 11:57:38 +00:00
|
|
|
|
}))
|
|
|
|
|
{
|
|
|
|
|
try
|
2017-01-15 14:09:48 +00:00
|
|
|
|
{
|
2017-04-15 00:54:19 +00:00
|
|
|
|
await Task.Delay(TimeSpan.FromHours(24), CancelToken).ConfigureAwait(false);
|
2017-01-15 14:09:48 +00:00
|
|
|
|
}
|
2017-02-06 11:57:38 +00:00
|
|
|
|
catch (OperationCanceledException)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
2017-04-15 00:54:19 +00:00
|
|
|
|
if (CancelToken.IsCancellationRequested)
|
2017-02-06 11:57:38 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_log.Warn("Stopping flower reaction event because it expired.");
|
|
|
|
|
await End();
|
2017-01-15 14:09:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|