2016-08-20 14:02:06 +00:00
|
|
|
using Discord;
|
|
|
|
using Discord.Commands;
|
|
|
|
using NadekoBot.Attributes;
|
|
|
|
using NadekoBot.Extensions;
|
2016-10-18 01:03:46 +00:00
|
|
|
using NLog;
|
2016-08-20 14:02:06 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Concurrent;
|
2016-09-03 13:04:07 +00:00
|
|
|
using System.Threading;
|
2016-08-20 14:02:06 +00:00
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
2016-08-20 20:35:27 +00:00
|
|
|
namespace NadekoBot.Modules.Administration
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
|
|
|
public partial class Administration
|
|
|
|
{
|
|
|
|
[Group]
|
2017-02-14 14:41:23 +00:00
|
|
|
public class RatelimitCommand : NadekoSubmodule
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2016-09-03 13:04:07 +00:00
|
|
|
public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
|
2017-02-14 19:35:10 +00:00
|
|
|
private new static readonly Logger _log;
|
2016-08-20 14:02:06 +00:00
|
|
|
|
2016-09-03 13:04:07 +00:00
|
|
|
public class Ratelimiter
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2016-09-03 13:04:07 +00:00
|
|
|
public class RatelimitedUser
|
|
|
|
{
|
|
|
|
public ulong UserId { get; set; }
|
|
|
|
public int MessageCount { get; set; } = 0;
|
|
|
|
}
|
2016-08-20 14:02:06 +00:00
|
|
|
|
2016-09-03 13:04:07 +00:00
|
|
|
public ulong ChannelId { get; set; }
|
2016-08-20 14:02:06 +00:00
|
|
|
|
2016-09-03 13:04:07 +00:00
|
|
|
public int MaxMessages { get; set; }
|
|
|
|
public int PerSeconds { get; set; }
|
|
|
|
|
2016-09-03 15:50:10 +00:00
|
|
|
public CancellationTokenSource cancelSource { get; set; } = new CancellationTokenSource();
|
2016-09-03 13:04:07 +00:00
|
|
|
|
2016-09-03 15:50:10 +00:00
|
|
|
public ConcurrentDictionary<ulong, RatelimitedUser> Users { get; set; } = new ConcurrentDictionary<ulong, RatelimitedUser>();
|
2016-09-03 13:04:07 +00:00
|
|
|
|
|
|
|
public bool CheckUserRatelimit(ulong id)
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2017-02-14 13:30:21 +00:00
|
|
|
var usr = Users.GetOrAdd(id, (key) => new RatelimitedUser() { UserId = id });
|
2016-09-03 13:04:07 +00:00
|
|
|
if (usr.MessageCount == MaxMessages)
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2016-09-03 13:04:07 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-02-14 13:30:21 +00:00
|
|
|
usr.MessageCount++;
|
|
|
|
var _ = Task.Run(async () =>
|
2016-09-03 13:04:07 +00:00
|
|
|
{
|
2017-02-14 13:30:21 +00:00
|
|
|
try
|
2016-12-28 06:56:44 +00:00
|
|
|
{
|
2017-02-14 13:30:21 +00:00
|
|
|
await Task.Delay(PerSeconds * 1000, cancelSource.Token);
|
|
|
|
}
|
|
|
|
catch (OperationCanceledException) { }
|
|
|
|
usr.MessageCount--;
|
|
|
|
});
|
|
|
|
return false;
|
2016-09-03 13:04:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-08 17:35:34 +00:00
|
|
|
static RatelimitCommand()
|
2016-09-03 13:04:07 +00:00
|
|
|
{
|
2016-12-28 06:56:44 +00:00
|
|
|
_log = LogManager.GetCurrentClassLogger();
|
2016-09-03 13:04:07 +00:00
|
|
|
|
2016-12-28 06:56:44 +00:00
|
|
|
NadekoBot.Client.MessageReceived += async (umsg) =>
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var usrMsg = umsg as IUserMessage;
|
2017-02-14 19:35:10 +00:00
|
|
|
var channel = usrMsg?.Channel as ITextChannel;
|
2016-09-03 13:04:07 +00:00
|
|
|
|
2016-12-28 06:56:44 +00:00
|
|
|
if (channel == null || usrMsg.IsAuthor())
|
|
|
|
return;
|
|
|
|
Ratelimiter limiter;
|
|
|
|
if (!RatelimitingChannels.TryGetValue(channel.Id, out limiter))
|
|
|
|
return;
|
2016-09-03 13:04:07 +00:00
|
|
|
|
2016-12-28 06:56:44 +00:00
|
|
|
if (limiter.CheckUserRatelimit(usrMsg.Author.Id))
|
|
|
|
await usrMsg.DeleteAsync();
|
|
|
|
}
|
|
|
|
catch (Exception ex) { _log.Warn(ex); }
|
|
|
|
};
|
2016-08-20 14:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-10-05 03:09:44 +00:00
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
2016-08-20 14:02:06 +00:00
|
|
|
[RequireContext(ContextType.Guild)]
|
2016-12-16 18:43:57 +00:00
|
|
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
|
|
|
public async Task Slowmode()
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2016-09-03 13:04:07 +00:00
|
|
|
Ratelimiter throwaway;
|
2016-12-17 00:16:14 +00:00
|
|
|
if (RatelimitingChannels.TryRemove(Context.Channel.Id, out throwaway))
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2016-09-03 15:50:10 +00:00
|
|
|
throwaway.cancelSource.Cancel();
|
2017-02-14 19:35:10 +00:00
|
|
|
await ReplyConfirmLocalized("slowmode_disabled").ConfigureAwait(false);
|
2016-08-20 14:02:06 +00:00
|
|
|
}
|
2016-10-19 11:17:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[NadekoCommand, Usage, Description, Aliases]
|
|
|
|
[RequireContext(ContextType.Guild)]
|
2016-12-16 18:43:57 +00:00
|
|
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
2016-12-17 00:16:14 +00:00
|
|
|
public async Task Slowmode(int msg, int perSec)
|
2016-10-19 11:17:18 +00:00
|
|
|
{
|
2016-12-17 00:16:14 +00:00
|
|
|
await Slowmode().ConfigureAwait(false); // disable if exists
|
|
|
|
|
2016-10-19 11:17:18 +00:00
|
|
|
if (msg < 1 || perSec < 1 || msg > 100 || perSec > 3600)
|
2016-09-03 13:04:07 +00:00
|
|
|
{
|
2017-02-14 19:35:10 +00:00
|
|
|
await ReplyErrorLocalized("invalid_params").ConfigureAwait(false);
|
2016-09-03 13:04:07 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-10-19 11:17:18 +00:00
|
|
|
var toAdd = new Ratelimiter()
|
|
|
|
{
|
2016-12-17 00:16:14 +00:00
|
|
|
ChannelId = Context.Channel.Id,
|
2016-09-03 15:50:10 +00:00
|
|
|
MaxMessages = msg,
|
|
|
|
PerSeconds = perSec,
|
2016-10-19 11:17:18 +00:00
|
|
|
};
|
2016-12-17 00:16:14 +00:00
|
|
|
if(RatelimitingChannels.TryAdd(Context.Channel.Id, toAdd))
|
2016-08-20 14:02:06 +00:00
|
|
|
{
|
2017-02-14 19:35:10 +00:00
|
|
|
await Context.Channel.SendConfirmAsync(GetText("slowmode_init"),
|
|
|
|
GetText("slowmode_desc", Format.Bold(toAdd.MaxMessages.ToString()), Format.Bold(toAdd.PerSeconds.ToString())))
|
2016-08-20 14:02:06 +00:00
|
|
|
.ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-28 06:56:44 +00:00
|
|
|
}
|