Ratelimiting done, untested
This commit is contained in:
parent
6d2c9970a7
commit
1c34b97e97
@ -5,9 +5,10 @@ using NadekoBot.Attributes;
|
|||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
//todo rewrite to accept msg/sec (for example 1/5 - 1 message every 5 seconds)
|
//todo rewrite
|
||||||
namespace NadekoBot.Modules.Administration
|
namespace NadekoBot.Modules.Administration
|
||||||
{
|
{
|
||||||
public partial class Administration
|
public partial class Administration
|
||||||
@ -15,58 +16,101 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[Group]
|
[Group]
|
||||||
public class RatelimitCommand
|
public class RatelimitCommand
|
||||||
{
|
{
|
||||||
public static ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, DateTime>> RatelimitingChannels = new ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, DateTime>>();
|
public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
|
||||||
|
|
||||||
private static readonly TimeSpan ratelimitTime = new TimeSpan(0, 0, 0, 5);
|
|
||||||
private DiscordSocketClient _client { get; }
|
private DiscordSocketClient _client { get; }
|
||||||
|
|
||||||
|
public class Ratelimiter
|
||||||
|
{
|
||||||
|
public class RatelimitedUser
|
||||||
|
{
|
||||||
|
public ulong UserId { get; set; }
|
||||||
|
public int MessageCount { get; set; } = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong ChannelId { get; set; }
|
||||||
|
|
||||||
|
public int MaxMessages { get; set; }
|
||||||
|
public int PerSeconds { get; set; }
|
||||||
|
|
||||||
|
public CancellationTokenSource cancelSource { get; set; }
|
||||||
|
public CancellationToken cancelToken { get; set; }
|
||||||
|
|
||||||
|
public ConcurrentDictionary<ulong, RatelimitedUser> Users { get; set; }
|
||||||
|
|
||||||
|
public bool CheckUserRatelimit(ulong id)
|
||||||
|
{
|
||||||
|
RatelimitedUser usr = Users.GetOrAdd(id, (key) => new RatelimitedUser() { UserId = id });
|
||||||
|
if (usr.MessageCount == MaxMessages)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usr.MessageCount++;
|
||||||
|
var t = Task.Run(async () => {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Task.Delay(PerSeconds * 1000, cancelToken);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) { }
|
||||||
|
usr.MessageCount--;
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public RatelimitCommand()
|
public RatelimitCommand()
|
||||||
{
|
{
|
||||||
|
|
||||||
this._client = NadekoBot.Client;
|
this._client = NadekoBot.Client;
|
||||||
|
|
||||||
_client.MessageReceived += async (umsg) =>
|
_client.MessageReceived += (umsg) =>
|
||||||
|
{
|
||||||
|
var t = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var usrMsg = umsg as IUserMessage;
|
var usrMsg = umsg as IUserMessage;
|
||||||
var channel = usrMsg.Channel as ITextChannel;
|
var channel = usrMsg.Channel as ITextChannel;
|
||||||
|
|
||||||
if (channel == null || await usrMsg.IsAuthor())
|
if (channel == null || await usrMsg.IsAuthor())
|
||||||
return;
|
return;
|
||||||
ConcurrentDictionary<ulong, DateTime> userTimePair;
|
Ratelimiter limiter;
|
||||||
if (!RatelimitingChannels.TryGetValue(channel.Id, out userTimePair)) return;
|
if (!RatelimitingChannels.TryGetValue(channel.Id, out limiter))
|
||||||
DateTime lastMessageTime;
|
|
||||||
if (userTimePair.TryGetValue(usrMsg.Author.Id, out lastMessageTime))
|
|
||||||
{
|
|
||||||
if (DateTime.Now - lastMessageTime < ratelimitTime)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await usrMsg.DeleteAsync().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
if (limiter.CheckUserRatelimit(usrMsg.Author.Id))
|
||||||
userTimePair.AddOrUpdate(usrMsg.Author.Id, id => DateTime.Now, (id, dt) => DateTime.Now);
|
await usrMsg.DeleteAsync();
|
||||||
|
});
|
||||||
|
return Task.CompletedTask;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task Slowmode(IUserMessage umsg)
|
public async Task Slowmode(IUserMessage umsg, int msg = 1, int perSec = 5)
|
||||||
{
|
{
|
||||||
var channel = (ITextChannel)umsg.Channel;
|
var channel = (ITextChannel)umsg.Channel;
|
||||||
|
|
||||||
ConcurrentDictionary<ulong, DateTime> throwaway;
|
Ratelimiter throwaway;
|
||||||
if (RatelimitingChannels.TryRemove(channel.Id, out throwaway))
|
if (RatelimitingChannels.TryRemove(channel.Id, out throwaway))
|
||||||
{
|
{
|
||||||
await channel.SendMessageAsync("Slow mode disabled.").ConfigureAwait(false);
|
await channel.SendMessageAsync("`Slow mode disabled.`").ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (RatelimitingChannels.TryAdd(channel.Id, new ConcurrentDictionary<ulong, DateTime>()))
|
|
||||||
|
if (msg < 1 || perSec < 1)
|
||||||
{
|
{
|
||||||
await channel.SendMessageAsync("Slow mode initiated. " +
|
await channel.SendMessageAsync("`Invalid parameters.`");
|
||||||
"Users can't send more than 1 message every 5 seconds.")
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RatelimitingChannels.TryAdd(channel.Id,throwaway = new Ratelimiter() {
|
||||||
|
ChannelId = channel.Id
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
await channel.SendMessageAsync("`Slow mode initiated.` " +
|
||||||
|
$"Users can't send more than {throwaway.MaxMessages} message(s) every {throwaway.PerSeconds} second(s).")
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
// todo rewrite
|
|
||||||
namespace NadekoBot.Modules.Games.Trivia
|
namespace NadekoBot.Modules.Games.Trivia
|
||||||
{
|
{
|
||||||
public class TriviaGame
|
public class TriviaGame
|
||||||
|
@ -417,7 +417,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
musicPlayer.RemoveSongAt(num - 1);
|
musicPlayer.RemoveSongAt(num - 1);
|
||||||
await channel.SendMessageAsync($"🎵**Track {song.PrettyName} at position `#{num}` has been removed.**").ConfigureAwait(false);
|
await channel.SendMessageAsync($"🎵**Track {song.PrettyName} at position `#{num}` has been removed.**").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
//todo fix
|
|
||||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task Remove(IUserMessage umsg, string all)
|
public async Task Remove(IUserMessage umsg, string all)
|
||||||
|
@ -117,7 +117,6 @@ namespace NadekoBot.Modules.Searches
|
|||||||
{
|
{
|
||||||
var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false);
|
var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false);
|
||||||
var smallObj = JArray.Parse(res)[0];
|
var smallObj = JArray.Parse(res)[0];
|
||||||
//todo check if successfull
|
|
||||||
var aniData = await http.GetStringAsync("http://anilist.co/api/manga/" + smallObj["id"] + $"?access_token={anilistToken}").ConfigureAwait(false);
|
var aniData = await http.GetStringAsync("http://anilist.co/api/manga/" + smallObj["id"] + $"?access_token={anilistToken}").ConfigureAwait(false);
|
||||||
|
|
||||||
return await Task.Run(() => JsonConvert.DeserializeObject<MangaResult>(aniData)).ConfigureAwait(false);
|
return await Task.Run(() => JsonConvert.DeserializeObject<MangaResult>(aniData)).ConfigureAwait(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user