public async Task SetRulesRaidProtection(ICommand command) { if (!Enum.TryParse <RaidProtectionRuleType>(command["Type"], out var type)) { throw new IncorrectParametersCommandException("Unknown rule type."); } RaidProtectionRule newRule; try { newRule = RaidProtectionRule.Create(type, command["Rule"]); } catch (Exception) { throw new IncorrectParametersCommandException("Invalid rule."); } await _settings.Modify((ulong)command["ServerId"], (RaidProtectionSettings x) => x.SetException(type, newRule)); await command.ReplySuccess($"Rule has been set."); }
private async Task EnforceRule(RaidProtectionRule rule, ICollection <IMessage> messages, ITextChannel channel, UserContext userContext, IGuildUser user, ulong logChannelId, string reason) { if (rule.Delete && (await channel.Guild.GetCurrentUserAsync()).GetPermissions(channel).ManageMessages) { foreach (var message in messages) { TaskHelper.FireForget(async() => await message.DeleteAsync()); } } if (rule.MaxOffenseCount > 0 && rule.OffenseWindow > TimeSpan.FromSeconds(0)) { bool punish = false; try { await userContext.Mutex.WaitAsync(); var offenses = userContext.Offenses.GetOrCreate(rule.Type); offenses.Add(messages.Last()); offenses.SlideWindow(rule.OffenseWindow); if (offenses.Count >= rule.MaxOffenseCount) { offenses.Clear(); punish = true; } } finally { userContext.Mutex.Release(); } var logger = _logger.WithScope(user); var currentUser = await channel.Guild.GetCurrentUserAsync(); if (currentUser.GetPermissions(channel).SendMessages) { IUserMessage warningMessage; if (punish) { await AdministrationHelpers.Mute(user, "raid protection rule", _settings); warningMessage = (await _communicator.SendMessage(channel, $"{user.Mention} you have been muted for breaking raid protection rules. If you believe this is a mistake, please contact a moderator.")).First(); } else { warningMessage = (await _communicator.SendMessage(channel, $"{user.Mention} you have broken a raid protection rule.")).First(); } warningMessage.DeleteAfter(8); } else { logger.LogInformation("Missing permissions to warn offender about rule {RaidProtectionRuleType}, punished: {Punished}", rule.Type, punish); } var logChannel = await channel.Guild.GetTextChannelAsync(logChannelId); if (logChannel != null && currentUser.GetPermissions(logChannel).SendMessages) { var embed = new EmbedBuilder() .WithFooter(fb => fb.WithText(messages.Last().Timestamp.ToUniversalTime().ToString(@"yyyy\/MM\/dd H:mm:ss UTC"))) .AddField(fb => fb.WithName("Reason").WithValue($"Broken rule ({rule.Type}).")); if (punish) { embed.WithDescription($"**Muted user {user.Mention} for suspicious behavior:**\n" + reason).WithColor(Color.Red); } else { embed.WithDescription($"**Warned user {user.Mention} for suspicious behavior:**\n" + reason).WithColor(Color.Orange); } await _communicator.SendMessage(logChannel, embed.Build()); } else { logger.LogInformation("Couldn't report about rule {RaidProtectionRuleType}, punished: {Punished}", rule.Type, punish); } logger.LogInformation("Enforced rule {RaidProtectionRuleType}, punished: {Punished}, reason: {RaidProtectionReason}", rule.Type, punish, reason); } }
public void SetException(RaidProtectionRuleType type, RaidProtectionRule rule) => Exceptions[type] = rule;