using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Discord; using Discord.WebSocket; using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Extensions; using NadekoBot.Modules.Administration.Common; using NadekoBot.Core.Services; using NadekoBot.Core.Services.Database.Models; using NLog; namespace NadekoBot.Modules.Administration.Services { public class SlowmodeService : IEarlyBlocker, INService { public ConcurrentDictionary RatelimitingChannels = new ConcurrentDictionary(); public ConcurrentDictionary> IgnoredRoles = new ConcurrentDictionary>(); public ConcurrentDictionary> IgnoredUsers = new ConcurrentDictionary>(); private readonly Logger _log; private readonly DiscordSocketClient _client; public SlowmodeService(DiscordSocketClient client, NadekoBot bot) { _log = LogManager.GetCurrentClassLogger(); _client = client; IgnoredRoles = new ConcurrentDictionary>( bot.AllGuildConfigs.ToDictionary(x => x.GuildId, x => new HashSet(x.SlowmodeIgnoredRoles.Select(y => y.RoleId)))); IgnoredUsers = new ConcurrentDictionary>( bot.AllGuildConfigs.ToDictionary(x => x.GuildId, x => new HashSet(x.SlowmodeIgnoredUsers.Select(y => y.UserId)))); } public async Task TryBlockEarly(IGuild guild, IUserMessage usrMsg) { if (guild == null) return false; try { var channel = usrMsg?.Channel as SocketTextChannel; if (channel == null || usrMsg == null || usrMsg.IsAuthor(_client)) return false; if (!RatelimitingChannels.TryGetValue(channel.Id, out Ratelimiter limiter)) return false; if (limiter.CheckUserRatelimit(usrMsg.Author.Id, channel.Guild.Id, usrMsg.Author as SocketGuildUser)) { await usrMsg.DeleteAsync(); return true; } } catch (Exception ex) { _log.Warn(ex); } return false; } } }