Files
nadekobot/src/NadekoBot/Modules/Administration/ProtectionCommands.cs

295 lines
12 KiB
C#

using System;
using Discord;
using Discord.Commands;
using NadekoBot.Common.Attributes;
using NadekoBot.Core.Services.Database.Models;
using NadekoBot.Extensions;
using NadekoBot.Modules.Administration.Common;
using NadekoBot.Modules.Administration.Services;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Core.Common.TypeReaders.Models;
namespace NadekoBot.Modules.Administration
{
public partial class Administration
{
[Group]
public class ProtectionCommands : NadekoSubmodule<ProtectionService>
{
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
public async Task AntiAlt()
{
if (await _service.TryStopAntiAlt(ctx.Guild.Id))
{
await ReplyConfirmLocalizedAsync("prot_disable", "Anti-Alt");
return;
}
await ReplyErrorLocalizedAsync("protection_not_running", "Anti-Alt");
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
public async Task AntiAlt(StoopidTime minAge, PunishmentAction action, [Leftover] StoopidTime punishTime = null)
{
var minAgeMinutes = (int)minAge.Time.TotalMinutes;
var punishTimeMinutes = (int?) punishTime?.Time.TotalMinutes ?? 0;
if (minAgeMinutes < 1 || punishTimeMinutes < 0)
return;
await _service.StartAntiAltAsync(ctx.Guild.Id, minAgeMinutes, action, (int?)punishTime?.Time.TotalMinutes ?? 0);
await ctx.OkAsync();
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
public async Task AntiAlt(StoopidTime minAge, PunishmentAction action, [Leftover]IRole role)
{
var minAgeMinutes = (int)minAge.Time.TotalMinutes;
if (minAgeMinutes < 1)
return;
await _service.StartAntiAltAsync(ctx.Guild.Id, minAgeMinutes, action, roleId: role.Id);
await ctx.OkAsync();
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
public Task AntiRaid()
{
if (_service.TryStopAntiRaid(ctx.Guild.Id))
{
return ReplyConfirmLocalizedAsync("prot_disable", "Anti-Raid");
}
else
{
return ReplyErrorLocalizedAsync("protection_not_running", "Anti-Raid");
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[Priority(1)]
public Task AntiRaid(int userThreshold, int seconds,
PunishmentAction action, [Leftover] StoopidTime punishTime)
=> InternalAntiRaid(userThreshold, seconds, action, punishTime: punishTime);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[Priority(2)]
public Task AntiRaid(int userThreshold, int seconds, PunishmentAction action)
=> InternalAntiRaid(userThreshold, seconds, action);
private async Task InternalAntiRaid(int userThreshold, int seconds = 10,
PunishmentAction action = PunishmentAction.Mute, StoopidTime punishTime = null)
{
if (action == PunishmentAction.AddRole)
{
await ReplyErrorLocalizedAsync("punishment_unsupported", action);
return;
}
if (userThreshold < 2 || userThreshold > 30)
{
await ReplyErrorLocalizedAsync("raid_cnt", 2, 30).ConfigureAwait(false);
return;
}
if (seconds < 2 || seconds > 300)
{
await ReplyErrorLocalizedAsync("raid_time", 2, 300).ConfigureAwait(false);
return;
}
if (punishTime is not null)
{
if (!_service.IsDurationAllowed(action))
{
await ReplyErrorLocalizedAsync("prot_cant_use_time");
}
}
var time = (int?) punishTime?.Time.TotalMinutes ?? 0;
if (time < 0 || time > 60 * 24)
return;
var stats = await _service.StartAntiRaidAsync(ctx.Guild.Id, userThreshold, seconds,
action, time).ConfigureAwait(false);
if (stats is null)
{
return;
}
await ctx.Channel.SendConfirmAsync(GetText("prot_enable", "Anti-Raid"),
$"{ctx.User.Mention} {GetAntiRaidString(stats)}")
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
public Task AntiSpam()
{
if (_service.TryStopAntiSpam(ctx.Guild.Id))
{
return ReplyConfirmLocalizedAsync("prot_disable", "Anti-Spam");
}
else
{
return ReplyErrorLocalizedAsync("protection_not_running", "Anti-Spam");
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[Priority(0)]
public Task AntiSpam(int messageCount, PunishmentAction action, [Leftover] IRole role)
{
if (action != PunishmentAction.AddRole)
return Task.CompletedTask;
return InternalAntiSpam(messageCount, action, null, role);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[Priority(1)]
public Task AntiSpam(int messageCount, PunishmentAction action, [Leftover] StoopidTime punishTime)
=> InternalAntiSpam(messageCount, action, punishTime, null);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[Priority(2)]
public Task AntiSpam(int messageCount, PunishmentAction action)
=> InternalAntiSpam(messageCount, action);
public async Task InternalAntiSpam(int messageCount, PunishmentAction action,
StoopidTime timeData = null, IRole role = null)
{
if (messageCount < 2 || messageCount > 10)
return;
if (timeData is not null)
{
if (!_service.IsDurationAllowed(action))
{
await ReplyErrorLocalizedAsync("prot_cant_use_time");
}
}
var time = (int?) timeData?.Time.TotalMinutes ?? 0;
if (time < 0 || time > 60 * 24)
return;
var stats = await _service.StartAntiSpamAsync(ctx.Guild.Id, messageCount, action, time, role?.Id).ConfigureAwait(false);
await ctx.Channel.SendConfirmAsync(GetText("prot_enable", "Anti-Spam"),
$"{ctx.User.Mention} {GetAntiSpamString(stats)}").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
public async Task AntispamIgnore()
{
var added = await _service.AntiSpamIgnoreAsync(ctx.Guild.Id, ctx.Channel.Id).ConfigureAwait(false);
if(added is null)
{
await ReplyErrorLocalizedAsync("protection_not_running", "Anti-Spam").ConfigureAwait(false);
return;
}
await ReplyConfirmLocalizedAsync(added.Value ? "spam_ignore" : "spam_not_ignore", "Anti-Spam").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task AntiList()
{
var (spam, raid, alt) = _service.GetAntiStats(ctx.Guild.Id);
if (spam is null && raid is null && alt is null)
{
await ReplyConfirmLocalizedAsync("prot_none").ConfigureAwait(false);
return;
}
var embed = new EmbedBuilder().WithOkColor()
.WithTitle(GetText("prot_active"));
if (spam != null)
embed.AddField(efb => efb.WithName("Anti-Spam")
.WithValue(GetAntiSpamString(spam).TrimTo(1024))
.WithIsInline(true));
if (raid != null)
embed.AddField(efb => efb.WithName("Anti-Raid")
.WithValue(GetAntiRaidString(raid).TrimTo(1024))
.WithIsInline(true));
if (alt is not null)
embed.AddField("Anti-Alt", GetAntiAltString(alt), true);
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
private string GetAntiAltString(AntiAltStats alt)
=> GetText("anti_alt_status",
Format.Bold(alt.MinAge.ToString(@"dd\d\ hh\h\ mm\m\ ")),
Format.Bold(alt.Action.ToString()),
Format.Bold(alt.Counter.ToString()));
private string GetAntiSpamString(AntiSpamStats stats)
{
var settings = stats.AntiSpamSettings;
var ignoredString = string.Join(", ", settings.IgnoredChannels.Select(c => $"<#{c.ChannelId}>"));
if (string.IsNullOrWhiteSpace(ignoredString))
ignoredString = "none";
string add = "";
if (settings.MuteTime > 0)
{
add = $" ({TimeSpan.FromMinutes(settings.MuteTime):hh\\hmm\\m})";
}
return GetText("spam_stats",
Format.Bold(settings.MessageThreshold.ToString()),
Format.Bold(settings.Action.ToString() + add),
ignoredString);
}
private string GetAntiRaidString(AntiRaidStats stats)
{
var actionString = Format.Bold(stats.AntiRaidSettings.Action.ToString());
if (stats.AntiRaidSettings.PunishDuration > 0)
{
actionString += $" **({TimeSpan.FromMinutes(stats.AntiRaidSettings.PunishDuration):hh\\hmm\\m})**";
}
return GetText("raid_stats",
Format.Bold(stats.AntiRaidSettings.UserThreshold.ToString()),
Format.Bold(stats.AntiRaidSettings.Seconds.ToString()),
actionString);
}
}
}
}