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);
            }
        }
Beispiel #3
0
 public void SetException(RaidProtectionRuleType type, RaidProtectionRule rule) => Exceptions[type] = rule;