diff --git a/Boyfriend/Boyfriend.cs b/Boyfriend/Boyfriend.cs
index 876bd20..77607fb 100644
--- a/Boyfriend/Boyfriend.cs
+++ b/Boyfriend/Boyfriend.cs
@@ -133,6 +133,6 @@ public static class Boyfriend {
return guild;
}
- throw new Exception(Messages.CouldntFindGuildByChannel);
+ throw new Exception("Could not find guild by channel!");
}
}
diff --git a/Boyfriend/Boyfriend.csproj b/Boyfriend/Boyfriend.csproj
index 8839dbb..a37a533 100644
--- a/Boyfriend/Boyfriend.csproj
+++ b/Boyfriend/Boyfriend.csproj
@@ -18,7 +18,6 @@
-
diff --git a/Boyfriend/CommandHandler.cs b/Boyfriend/CommandHandler.cs
deleted file mode 100644
index a8eed4d..0000000
--- a/Boyfriend/CommandHandler.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using System.Text;
-using System.Text.RegularExpressions;
-using Boyfriend.Commands;
-using Discord;
-using Discord.Commands;
-using Discord.WebSocket;
-
-namespace Boyfriend;
-
-public static class CommandHandler {
- public static readonly Command[] Commands = {
- new BanCommand(), new ClearCommand(), new HelpCommand(),
- new KickCommand(), new MuteCommand(), new PingCommand(),
- new SettingsCommand(), new UnbanCommand(), new UnmuteCommand()
- };
-
- private static readonly Dictionary RegexCache = new();
- private static readonly Regex MentionRegex = new(Regex.Escape("<@855023234407333888>"));
-
- public static readonly StringBuilder StackedReplyMessage = new();
- public static readonly StringBuilder StackedPublicFeedback = new();
- public static readonly StringBuilder StackedPrivateFeedback = new();
-
-#pragma warning disable CA2211
- public static bool ConfigWriteScheduled = false; // Can't be private
-#pragma warning restore CA2211
-
- private static bool _handlerBusy;
-
- public static async Task HandleCommand(SocketUserMessage message) {
- while (_handlerBusy) await Task.Delay(200);
- _handlerBusy = true;
- StackedReplyMessage.Clear();
- StackedPrivateFeedback.Clear();
- StackedPublicFeedback.Clear();
- var context = new SocketCommandContext(Boyfriend.Client, message);
- var guild = context.Guild;
- var config = Boyfriend.GetGuildConfig(guild.Id);
-
- Regex regex;
- if (RegexCache.ContainsKey(config["Prefix"])) { regex = RegexCache[config["Prefix"]]; } else {
- regex = new Regex(Regex.Escape(config["Prefix"]));
- RegexCache.Add(config["Prefix"], regex);
- }
-
- var list = message.Content.Split("\n");
- var currentLine = 0;
- foreach (var line in list) {
- currentLine++;
- await RunCommands(line, regex, context, currentLine == list.Length);
- }
-
- if (ConfigWriteScheduled) await Boyfriend.WriteGuildConfig(guild.Id);
-
- var adminChannel = Utils.GetAdminLogChannel(guild.Id);
- var systemChannel = guild.SystemChannel;
- if (StackedPrivateFeedback.Length > 0 && adminChannel != null && adminChannel.Id != message.Channel.Id)
- await Utils.SilentSendAsync(adminChannel, StackedPrivateFeedback.ToString());
- if (StackedPublicFeedback.Length > 0 && systemChannel != null && systemChannel.Id != adminChannel?.Id
- && systemChannel.Id != message.Channel.Id)
- await Utils.SilentSendAsync(systemChannel, StackedPublicFeedback.ToString());
- _handlerBusy = false;
- }
-
- private static async Task RunCommands(string line, Regex regex, SocketCommandContext context, bool shouldAwait) {
- foreach (var command in Commands) {
- var lineNoMention = MentionRegex.Replace(line, "", 1);
- if (!command.Aliases.Contains(regex.Replace(lineNoMention, "", 1).Trim().ToLower().Split()[0]))
- continue;
-
- await context.Channel.TriggerTypingAsync();
-
- var args = line.Split().Skip(1).ToArray();
-
- if (command.ArgsLengthRequired <= args.Length)
- if (shouldAwait)
- await command.Run(context, args);
- else
- _ = command.Run(context, args);
- else
- StackedReplyMessage.AppendFormat(Messages.NotEnoughArguments, command.ArgsLengthRequired.ToString(),
- args.Length.ToString()).AppendLine();
- if (StackedReplyMessage.Length <= 1675 && !shouldAwait) continue;
- await context.Message.ReplyAsync(StackedReplyMessage.ToString(), false, null, AllowedMentions.None);
- StackedReplyMessage.Clear();
- }
- }
-
- public static string HasPermission(ref SocketGuildUser user, GuildPermission toCheck,
- GuildPermission forBot = GuildPermission.StartEmbeddedActivities) {
- var me = user.Guild.CurrentUser;
-
- if (user.Id == user.Guild.OwnerId || (me.GuildPermissions.Has(GuildPermission.Administrator) &&
- user.GuildPermissions.Has(GuildPermission.Administrator))) return "";
-
- if (forBot == GuildPermission.StartEmbeddedActivities) forBot = toCheck;
-
- if (!me.GuildPermissions.Has(forBot))
- return Messages.CommandNoPermissionBot;
-
- return !user.GuildPermissions.Has(toCheck) ? Messages.CommandNoPermissionUser : "";
- }
-
- public static string CanInteract(ref SocketGuildUser actor, ref SocketGuildUser target) {
- if (actor.Guild != target.Guild)
- return Messages.InteractionsDifferentGuilds;
- if (actor.Id == actor.Guild.OwnerId)
- return "";
-
- if (target.Id == target.Guild.OwnerId)
- return Messages.InteractionsOwner;
- if (actor == target)
- return Messages.InteractionsYourself;
-
- var me = target.Guild.CurrentUser;
-
- if (target == me)
- return Messages.InteractionsMe;
- if (me.Hierarchy <= target.Hierarchy)
- return Messages.InteractionsFailedBot;
-
- return actor.Hierarchy <= target.Hierarchy ? Messages.InteractionsFailedUser : "";
- }
-}
diff --git a/Boyfriend/CommandProcessor.cs b/Boyfriend/CommandProcessor.cs
new file mode 100644
index 0000000..2d83b54
--- /dev/null
+++ b/Boyfriend/CommandProcessor.cs
@@ -0,0 +1,271 @@
+using System.Text;
+using System.Text.RegularExpressions;
+using Boyfriend.Commands;
+using Discord;
+using Discord.Commands;
+using Discord.WebSocket;
+
+namespace Boyfriend;
+
+public class CommandProcessor {
+ private const string Success = ":white_check_mark: ";
+ private const string MissingArgument = ":keyboard: ";
+ private const string InvalidArgument = ":construction: ";
+ private const string NoAccess = ":no_entry_sign: ";
+ private const string CantInteract = ":vertical_traffic_light: ";
+
+ public static readonly Command[] Commands = {
+ new BanCommand(), new ClearCommand(), new HelpCommand(),
+ new KickCommand(), new MuteCommand(), new PingCommand(),
+ new SettingsCommand(), new UnbanCommand(), new UnmuteCommand()
+ };
+
+ private static readonly Dictionary RegexCache = new();
+ private static readonly Regex MentionRegex = new(Regex.Escape("<@855023234407333888>"));
+ private readonly StringBuilder _stackedPrivateFeedback = new();
+ private readonly StringBuilder _stackedPublicFeedback = new();
+ private readonly StringBuilder _stackedReplyMessage = new();
+ private readonly List _tasks = new();
+
+ public readonly SocketCommandContext Context;
+
+ public bool ConfigWriteScheduled = false;
+
+ public CommandProcessor(SocketUserMessage message) {
+ Context = new SocketCommandContext(Boyfriend.Client, message);
+ }
+
+ public async Task HandleCommand() {
+ _stackedReplyMessage.Clear();
+ _stackedPrivateFeedback.Clear();
+ _stackedPublicFeedback.Clear();
+ var guild = Context.Guild;
+ var config = Boyfriend.GetGuildConfig(guild.Id);
+
+ if (GetMember().Roles.Contains(Utils.GetMuteRole(guild))) {
+ await Context.Message.ReplyAsync(Messages.UserCannotUnmuteThemselves);
+ return;
+ }
+
+ Regex regex;
+ if (RegexCache.ContainsKey(config["Prefix"])) { regex = RegexCache[config["Prefix"]]; } else {
+ regex = new Regex(Regex.Escape(config["Prefix"]));
+ RegexCache.Add(config["Prefix"], regex);
+ }
+
+ var list = Context.Message.Content.Split("\n");
+ foreach (var line in list) {
+ RunCommandOnLine(line, regex);
+ if (_stackedReplyMessage.Length > 0) _ = Context.Channel.TriggerTypingAsync();
+ }
+
+ await Task.WhenAll(_tasks);
+
+ if (ConfigWriteScheduled) await Boyfriend.WriteGuildConfig(guild.Id);
+
+ if (_stackedReplyMessage.Length > 0) _ = Context.Message.ReplyAsync(_stackedReplyMessage.ToString());
+
+ var adminChannel = Utils.GetAdminLogChannel(guild.Id);
+ var systemChannel = guild.SystemChannel;
+ if (_stackedPrivateFeedback.Length > 0 && adminChannel != null && adminChannel.Id != Context.Message.Channel.Id)
+ _ = Utils.SilentSendAsync(adminChannel, _stackedPrivateFeedback.ToString());
+ if (_stackedPublicFeedback.Length > 0 && systemChannel != null && systemChannel.Id != adminChannel?.Id
+ && systemChannel.Id != Context.Message.Channel.Id)
+ _ = Utils.SilentSendAsync(systemChannel, _stackedPublicFeedback.ToString());
+ }
+
+ private void RunCommandOnLine(string line, Regex regex) {
+ foreach (var command in Commands) {
+ var lineNoMention = regex.Replace(MentionRegex.Replace(line, "", 1), "", 1);
+ if (lineNoMention == line
+ || !command.Aliases.Contains(regex.Replace(lineNoMention, "", 1).Trim().ToLower().Split()[0]))
+ continue;
+
+ var args = line.Split().Skip(1).ToArray();
+ _tasks.Add(command.Run(this, args));
+ }
+ }
+
+ public void Reply(string response, string? customEmoji = null) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $"{customEmoji ?? Success}{response}", Context.Message);
+ }
+
+ public void Audit(string action, bool isPublic = true) {
+ var format = string.Format(Messages.FeedbackFormat, Context.User.Mention, action);
+ if (isPublic) Utils.SafeAppendToBuilder(_stackedPublicFeedback, format, Context.Guild.SystemChannel);
+ Utils.SafeAppendToBuilder(_stackedPrivateFeedback, format, Utils.GetAdminLogChannel(Context.Guild.Id));
+ }
+
+ public string? GetRemaining(string[] from, int startIndex, string? argument) {
+ if (startIndex >= from.Length && argument != null)
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{MissingArgument}{Utils.GetMessage($"Missing{argument}")}", Context.Message);
+ else
+ return string.Join(" ", from, startIndex, from.Length - startIndex);
+ return null;
+ }
+
+ public SocketUser? GetUser(string[] args, int index, string? argument) {
+ if (index >= args.Length) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $"{MissingArgument}{Messages.MissingUser}",
+ Context.Message);
+ return null;
+ }
+
+ var user = Utils.ParseUser(args[index]);
+ if (user == null && argument != null)
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{InvalidArgument}{string.Format(Messages.InvalidUser, args[index])}", Context.Message);
+ return user;
+ }
+
+ public bool HasPermission(GuildPermission permission) {
+ if (!Context.Guild.CurrentUser.GuildPermissions.Has(permission)) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $"{NoAccess}{Utils.GetMessage($"BotCannot{permission}")}",
+ Context.Message);
+ return false;
+ }
+
+ if (Context.Guild.GetUser(Context.User.Id).GuildPermissions.Has(permission)
+ || Context.Guild.Owner.Id == Context.User.Id) return true;
+
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $"{NoAccess}{Utils.GetMessage($"UserCannot{permission}")}",
+ Context.Message);
+ return false;
+ }
+
+ public SocketGuildUser? GetMember(SocketUser user, string? argument) {
+ var member = Context.Guild.GetUser(user.Id);
+ if (member == null && argument != null)
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $":x: {Messages.UserNotInGuild}", Context.Message);
+ return member;
+ }
+
+ public SocketGuildUser? GetMember(string[] args, int index, string? argument) {
+ if (index >= args.Length) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $"{MissingArgument}{Messages.MissingMember}",
+ Context.Message);
+ return null;
+ }
+
+ var member = Context.Guild.GetUser(Utils.ParseMention(args[index]));
+ if (member == null && argument != null)
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{InvalidArgument}{string.Format(Messages.InvalidMember, Utils.Wrap(args[index]))}", Context.Message);
+ return member;
+ }
+
+ private SocketGuildUser GetMember() {
+ return Context.Guild.GetUser(Context.User.Id);
+ }
+
+ public ulong? GetBan(string[] args, int index) {
+ if (index >= args.Length) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, $"{MissingArgument}{Messages.MissingUser}",
+ Context.Message);
+ return null;
+ }
+
+ var id = Utils.ParseMention(args[index]);
+ if (Context.Guild.GetBanAsync(id) != null) return id;
+ Utils.SafeAppendToBuilder(_stackedReplyMessage, Messages.UserNotBanned, Context.Message);
+ return null;
+ }
+
+ public int? GetNumberRange(string[] args, int index, int min, int max, string? argument) {
+ if (index >= args.Length) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{MissingArgument}{string.Format(Messages.MissingNumber, min.ToString(), max.ToString())}",
+ Context.Message);
+ return null;
+ }
+
+ if (!int.TryParse(args[index], out var i)) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{InvalidArgument}{string.Format(Utils.GetMessage($"{argument}Invalid"), min.ToString(), max.ToString(), Utils.Wrap(args[index]))}",
+ Context.Message);
+ return null;
+ }
+
+ if (argument == null) return i;
+ if (i < min) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{InvalidArgument}{string.Format(Utils.GetMessage($"{argument}TooSmall"), min.ToString())}",
+ Context.Message);
+ return null;
+ }
+
+ if (i <= max) return i;
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{InvalidArgument}{string.Format(Utils.GetMessage($"{argument}TooLarge"), max.ToString())}",
+ Context.Message);
+ return null;
+ }
+
+ public static TimeSpan GetTimeSpan(string[] args, int index) {
+ var infinity = TimeSpan.FromMilliseconds(-1);
+ if (index >= args.Length)
+ return infinity;
+ var chars = args[index].AsSpan();
+ var numberBuilder = Boyfriend.StringBuilder;
+ int days = 0, hours = 0, minutes = 0, seconds = 0;
+ foreach (var c in chars)
+ if (char.IsDigit(c)) { numberBuilder.Append(c); } else {
+ if (numberBuilder.Length == 0) return infinity;
+ switch (c) {
+ case 'd' or 'D' or 'д' or 'Д':
+ days += int.Parse(numberBuilder.ToString());
+ numberBuilder.Clear();
+ break;
+ case 'h' or 'H' or 'ч' or 'Ч':
+ hours += int.Parse(numberBuilder.ToString());
+ numberBuilder.Clear();
+ break;
+ case 'm' or 'M' or 'м' or 'М':
+ minutes += int.Parse(numberBuilder.ToString());
+ numberBuilder.Clear();
+ break;
+ case 's' or 'S' or 'с' or 'С':
+ seconds += int.Parse(numberBuilder.ToString());
+ numberBuilder.Clear();
+ break;
+ default: return infinity;
+ }
+ }
+
+ numberBuilder.Clear();
+ return new TimeSpan(days, hours, minutes, seconds);
+ }
+
+ public bool CanInteractWith(SocketGuildUser user, string action) {
+ if (Context.Guild.Owner.Id == Context.User.Id) return true;
+ if (Context.Guild.Owner.Id == user.Id) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{CantInteract}{Utils.GetMessage($"UserCannot{action}Owner")}", Context.Message);
+ return false;
+ }
+
+ if (Context.User.Id == user.Id) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{CantInteract}{Utils.GetMessage($"UserCannot{action}Themselves")}", Context.Message);
+ return false;
+ }
+
+ if (Context.Guild.CurrentUser.Id == user.Id) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{CantInteract}{Utils.GetMessage($"UserCannot{action}Bot")}", Context.Message);
+ return false;
+ }
+
+ if (Context.Guild.CurrentUser.Hierarchy <= user.Hierarchy) {
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{CantInteract}{Utils.GetMessage($"BotCannot{action}Target")}", Context.Message);
+ return false;
+ }
+
+ if (GetMember().Hierarchy > user.Hierarchy) return true;
+ Utils.SafeAppendToBuilder(_stackedReplyMessage,
+ $"{CantInteract}{Utils.GetMessage($"UserCannot{action}Target")}", Context.Message);
+ return false;
+ }
+}
diff --git a/Boyfriend/Commands/BanCommand.cs b/Boyfriend/Commands/BanCommand.cs
index 0f67c81..7e42b6a 100644
--- a/Boyfriend/Commands/BanCommand.cs
+++ b/Boyfriend/Commands/BanCommand.cs
@@ -1,74 +1,44 @@
using Discord;
-using Discord.Commands;
using Discord.WebSocket;
namespace Boyfriend.Commands;
public class BanCommand : Command {
public override string[] Aliases { get; } = { "ban", "бан" };
- public override int ArgsLengthRequired => 2;
- public override async Task Run(SocketCommandContext context, string[] args) {
- var toBan = Utils.ParseUser(args[0]);
+ public override async Task Run(CommandProcessor cmd, string[] args) {
+ var toBan = cmd.GetUser(args, 0, "ToBan");
+ if (toBan == null || !cmd.HasPermission(GuildPermission.BanMembers)) return;
- if (toBan == null) {
- Error(Messages.UserDoesntExist, false);
- return;
- }
+ var memberToBan = cmd.GetMember(toBan, null);
+ if (memberToBan != null && !cmd.CanInteractWith(memberToBan, "Ban")) return;
- var guild = context.Guild;
- var author = (SocketGuildUser)context.User;
+ var duration = CommandProcessor.GetTimeSpan(args, 1);
+ var reason = cmd.GetRemaining(args, duration.TotalSeconds < 1 ? 1 : 2, "BanReason");
+ if (reason == null) return;
- var permissionCheckResponse = CommandHandler.HasPermission(ref author, GuildPermission.BanMembers);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return;
- }
-
- var reason = Utils.JoinString(ref args, 2);
- var memberToBan = Utils.ParseMember(guild, args[0]);
-
- if (memberToBan != null) {
- var interactionCheckResponse = CommandHandler.CanInteract(ref author, ref memberToBan);
- if (interactionCheckResponse is not "") {
- Error(interactionCheckResponse, true);
- return;
- }
- }
-
- var duration = Utils.GetTimeSpan(ref args[1]) ?? TimeSpan.FromMilliseconds(-1);
- if (duration.TotalSeconds < 0) {
- Warn(Messages.DurationParseFailed);
- reason = Utils.JoinString(ref args, 1);
-
- if (reason is "") {
- Error(Messages.ReasonRequired, false);
- return;
- }
- }
-
- await BanUser(guild, author, toBan, duration, reason);
+ await BanUser(cmd, toBan, duration, reason);
}
- public static async Task BanUser(SocketGuild guild, SocketGuildUser author, SocketUser toBan, TimeSpan duration,
- string reason) {
- var guildBanMessage = $"({author}) {reason}";
-
+ public static async Task BanUser(CommandProcessor cmd, SocketUser toBan, TimeSpan duration, string reason) {
+ var author = cmd.Context.User;
+ var guild = cmd.Context.Guild;
await Utils.SendDirectMessage(toBan,
string.Format(Messages.YouWereBanned, author.Mention, guild.Name, Utils.Wrap(reason)));
+ var guildBanMessage = $"({author}) {reason}";
await guild.AddBanAsync(toBan, 0, guildBanMessage);
var feedback = string.Format(Messages.FeedbackUserBanned, toBan.Mention,
- Utils.GetHumanizedTimeOffset(ref duration), Utils.Wrap(reason));
- Success(feedback, author.Mention, false, false);
- await Utils.SendFeedback(feedback, guild.Id, author.Mention, true);
+ Utils.GetHumanizedTimeOffset(duration), Utils.Wrap(reason));
+ cmd.Reply(feedback, ":hammer: ");
+ cmd.Audit(feedback);
if (duration.TotalSeconds > 0) {
var _ = async () => {
await Task.Delay(duration);
- await UnbanCommand.UnbanUser(guild, guild.CurrentUser, toBan, Messages.PunishmentExpired);
+ await UnbanCommand.UnbanUser(cmd, toBan.Id, Messages.PunishmentExpired);
};
}
}
-}
+}
\ No newline at end of file
diff --git a/Boyfriend/Commands/ClearCommand.cs b/Boyfriend/Commands/ClearCommand.cs
index 6b51075..164e0c6 100644
--- a/Boyfriend/Commands/ClearCommand.cs
+++ b/Boyfriend/Commands/ClearCommand.cs
@@ -1,46 +1,23 @@
using Discord;
-using Discord.Commands;
using Discord.WebSocket;
namespace Boyfriend.Commands;
public class ClearCommand : Command {
public override string[] Aliases { get; } = { "clear", "purge", "очистить", "стереть" };
- public override int ArgsLengthRequired => 1;
- public override async Task Run(SocketCommandContext context, string[] args) {
- var user = (SocketGuildUser)context.User;
+ public override async Task Run(CommandProcessor cmd, string[] args) {
+ if (cmd.Context.Channel is not SocketTextChannel channel) throw new Exception();
- if (context.Channel is not SocketTextChannel channel) throw new Exception();
+ if (!cmd.HasPermission(GuildPermission.ManageMessages)) return;
- var permissionCheckResponse = CommandHandler.HasPermission(ref user, GuildPermission.ManageMessages);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return;
- }
+ var toDelete = cmd.GetNumberRange(args, 0, 1, 200, "ClearAmount");
+ if (toDelete == null) return;
+ var messages = await channel.GetMessagesAsync((int)(toDelete + 1)).FlattenAsync();
- if (!int.TryParse(args[0], out var toDelete)) {
- Error(Messages.ClearInvalidAmountSpecified, false);
- return;
- }
+ var user = (SocketGuildUser)cmd.Context.User;
+ await channel.DeleteMessagesAsync(messages, Utils.GetRequestOptions(user.ToString()!));
- switch (toDelete) {
- case < 1:
- Error(Messages.ClearNegativeAmount, false);
- break;
- case > 200:
- Error(Messages.ClearAmountTooLarge, false);
- break;
- default:
- var messages = await channel.GetMessagesAsync(toDelete + 1).FlattenAsync();
-
- await channel.DeleteMessagesAsync(messages, Utils.GetRequestOptions(user.ToString()!));
-
- await Utils.SendFeedback(
- string.Format(Messages.FeedbackMessagesCleared, (toDelete + 1).ToString(), channel.Mention),
- context.Guild.Id, user.Mention);
-
- break;
- }
+ cmd.Audit(string.Format(Messages.FeedbackMessagesCleared, (toDelete + 1).ToString()));
}
}
\ No newline at end of file
diff --git a/Boyfriend/Commands/Command.cs b/Boyfriend/Commands/Command.cs
index ec8590b..cf8563b 100644
--- a/Boyfriend/Commands/Command.cs
+++ b/Boyfriend/Commands/Command.cs
@@ -1,31 +1,7 @@
-using System.Text;
-using Discord.Commands;
-
-namespace Boyfriend.Commands;
+namespace Boyfriend.Commands;
public abstract class Command {
public abstract string[] Aliases { get; }
- public abstract int ArgsLengthRequired { get; }
- public abstract Task Run(SocketCommandContext context, string[] args);
-
- protected static void Output(ref StringBuilder message) {
- CommandHandler.StackedReplyMessage.Append(message).AppendLine();
- }
-
- protected static void Success(string message, string userMention, bool sendPublicFeedback = false,
- bool sendPrivateFeedback = true) {
- CommandHandler.StackedReplyMessage.Append(":white_check_mark: ").AppendLine(message);
- if (sendPrivateFeedback)
- Utils.StackFeedback(ref message, ref userMention, sendPublicFeedback);
- }
-
- protected static void Warn(string message) {
- CommandHandler.StackedReplyMessage.Append(":warning: ").AppendLine(message);
- }
-
- protected static void Error(string message, bool accessDenied) {
- var symbol = accessDenied ? ":no_entry_sign: " : ":x: ";
- CommandHandler.StackedReplyMessage.Append(symbol).AppendLine(message);
- }
+ public abstract Task Run(CommandProcessor cmd, string[] args);
}
\ No newline at end of file
diff --git a/Boyfriend/Commands/HelpCommand.cs b/Boyfriend/Commands/HelpCommand.cs
index 656fa48..1a27bcd 100644
--- a/Boyfriend/Commands/HelpCommand.cs
+++ b/Boyfriend/Commands/HelpCommand.cs
@@ -1,20 +1,18 @@
-using Discord.Commands;
-using Humanizer;
+using Humanizer;
namespace Boyfriend.Commands;
public class HelpCommand : Command {
- public override string[] Aliases { get; } = {"help", "помощь", "справка"};
- public override int ArgsLengthRequired => 0;
+ public override string[] Aliases { get; } = { "help", "помощь", "справка" };
- public override Task Run(SocketCommandContext context, string[] args) {
- var prefix = Boyfriend.GetGuildConfig(context.Guild.Id)["Prefix"];
+ public override Task Run(CommandProcessor cmd, string[] args) {
+ var prefix = Boyfriend.GetGuildConfig(cmd.Context.Guild.Id)["Prefix"];
var toSend = Boyfriend.StringBuilder.Append(Messages.CommandHelp);
- foreach (var command in CommandHandler.Commands)
+ foreach (var command in CommandProcessor.Commands)
toSend.Append(
$"\n`{prefix}{command.Aliases[0]}`: {Utils.GetMessage($"CommandDescription{command.Aliases[0].Titleize()}")}");
- Output(ref toSend);
+ cmd.Reply(toSend.ToString(), ":page_facing_up: ");
toSend.Clear();
return Task.CompletedTask;
diff --git a/Boyfriend/Commands/KickCommand.cs b/Boyfriend/Commands/KickCommand.cs
index fa1ab32..ba1a139 100644
--- a/Boyfriend/Commands/KickCommand.cs
+++ b/Boyfriend/Commands/KickCommand.cs
@@ -1,49 +1,31 @@
using Discord;
-using Discord.Commands;
using Discord.WebSocket;
namespace Boyfriend.Commands;
public class KickCommand : Command {
public override string[] Aliases { get; } = { "kick", "кик", "выгнать" };
- public override int ArgsLengthRequired => 2;
- public override async Task Run(SocketCommandContext context, string[] args) {
- var author = (SocketGuildUser)context.User;
+ public override async Task Run(CommandProcessor cmd, string[] args) {
+ var toKick = cmd.GetMember(args, 0, "ToKick");
+ if (toKick == null || !cmd.HasPermission(GuildPermission.KickMembers)) return;
- var permissionCheckResponse = CommandHandler.HasPermission(ref author, GuildPermission.KickMembers);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return;
- }
+ if (!cmd.CanInteractWith(toKick, "Kick")) return;
- var toKick = Utils.ParseMember(context.Guild, args[0]);
-
- if (toKick == null) {
- Error(Messages.UserNotInGuild, false);
- return;
- }
-
- var interactionCheckResponse = CommandHandler.CanInteract(ref author, ref toKick);
- if (interactionCheckResponse is not "") {
- Error(interactionCheckResponse, true);
- return;
- }
-
- await KickMember(context.Guild, author, toKick, Utils.JoinString(ref args, 1));
-
- Success(
- string.Format(Messages.FeedbackMemberKicked, toKick.Mention,
- Utils.Wrap(Utils.JoinString(ref args, 1))), author.Mention);
+ await KickMember(cmd, toKick, cmd.GetRemaining(args, 1, "KickReason"));
}
- private static async Task KickMember(IGuild guild, SocketUser author, SocketGuildUser toKick, string reason) {
- var authorMention = author.Mention;
- var guildKickMessage = $"({author}) {reason}";
+ private static async Task KickMember(CommandProcessor cmd, SocketGuildUser toKick, string? reason) {
+ if (reason == null) return;
+ var guildKickMessage = $"({cmd.Context.User}) {reason}";
await Utils.SendDirectMessage(toKick,
- string.Format(Messages.YouWereKicked, authorMention, guild.Name, Utils.Wrap(reason)));
+ string.Format(Messages.YouWereKicked, cmd.Context.User.Mention, cmd.Context.Guild.Name,
+ Utils.Wrap(reason)));
await toKick.KickAsync(guildKickMessage);
+ var format = string.Format(Messages.FeedbackMemberKicked, toKick.Mention, Utils.Wrap(reason));
+ cmd.Reply(format, ":police_car: ");
+ cmd.Audit(format);
}
}
\ No newline at end of file
diff --git a/Boyfriend/Commands/MuteCommand.cs b/Boyfriend/Commands/MuteCommand.cs
index d9b61d7..c972614 100644
--- a/Boyfriend/Commands/MuteCommand.cs
+++ b/Boyfriend/Commands/MuteCommand.cs
@@ -1,5 +1,4 @@
using Discord;
-using Discord.Commands;
using Discord.Net;
using Discord.WebSocket;
@@ -7,72 +6,45 @@ namespace Boyfriend.Commands;
public class MuteCommand : Command {
public override string[] Aliases { get; } = { "mute", "timeout", "заглушить", "мут" };
- public override int ArgsLengthRequired => 2;
- public override async Task Run(SocketCommandContext context, string[] args) {
- var toMute = Utils.ParseMember(context.Guild, args[0]);
- var reason = Utils.JoinString(ref args, 2);
+ public override async Task Run(CommandProcessor cmd, string[] args) {
+ var toMute = cmd.GetMember(args, 0, "ToMute");
+ if (toMute == null) return;
- var duration = Utils.GetTimeSpan(ref args[1]) ?? TimeSpan.FromMilliseconds(-1);
- if (duration.TotalSeconds < 0) {
- Warn(Messages.DurationParseFailed);
- reason = Utils.JoinString(ref args, 1);
- }
-
-
- if (reason is "") {
- Error(Messages.ReasonRequired, false);
- return;
- }
-
- if (toMute == null) {
- Error(Messages.UserNotInGuild, false);
- return;
- }
-
- var guild = context.Guild;
- var role = Utils.GetMuteRole(ref guild);
+ var duration = CommandProcessor.GetTimeSpan(args, 1);
+ var reason = cmd.GetRemaining(args, duration.TotalSeconds < 1 ? 1 : 2, "MuteReason");
+ if (reason == null) return;
+ var role = Utils.GetMuteRole(cmd.Context.Guild);
if (role != null) {
if (toMute.Roles.Contains(role) || (toMute.TimedOutUntil != null &&
toMute.TimedOutUntil.Value.ToUnixTimeMilliseconds() >
DateTimeOffset.Now.ToUnixTimeMilliseconds())) {
- Error(Messages.MemberAlreadyMuted, false);
+ cmd.Reply(Messages.MemberAlreadyMuted, ":x: ");
return;
}
}
- var rolesRemoved = Boyfriend.GetRemovedRoles(context.Guild.Id);
+ var rolesRemoved = Boyfriend.GetRemovedRoles(cmd.Context.Guild.Id);
if (rolesRemoved.ContainsKey(toMute.Id)) {
foreach (var roleId in rolesRemoved[toMute.Id]) await toMute.AddRoleAsync(roleId);
rolesRemoved.Remove(toMute.Id);
- CommandHandler.ConfigWriteScheduled = true;
- Warn(Messages.RolesReturned);
+ cmd.ConfigWriteScheduled = true;
+ cmd.Reply(Messages.RolesReturned, ":warning: ");
}
- var author = (SocketGuildUser)context.User;
+ if (!cmd.HasPermission(GuildPermission.ModerateMembers) || !cmd.CanInteractWith(toMute, "Mute")) return;
- var permissionCheckResponse = CommandHandler.HasPermission(ref author, GuildPermission.ModerateMembers);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return;
- }
-
- var interactionCheckResponse = CommandHandler.CanInteract(ref author, ref toMute);
- if (interactionCheckResponse is not "") {
- Error(interactionCheckResponse, true);
- return;
- }
-
- await MuteMember(guild, author, toMute, duration, reason);
+ await MuteMember(cmd, toMute, duration, reason);
}
- private static async Task MuteMember(SocketGuild guild, SocketUser author, SocketGuildUser toMute,
+ private static async Task MuteMember(CommandProcessor cmd, SocketGuildUser toMute,
TimeSpan duration, string reason) {
+ var guild = cmd.Context.Guild;
var config = Boyfriend.GetGuildConfig(guild.Id);
- var requestOptions = Utils.GetRequestOptions($"({author}) {reason}");
- var role = Utils.GetMuteRole(ref guild);
+ var requestOptions = Utils.GetRequestOptions($"({cmd.Context.User}) {reason}");
+ var role = Utils.GetMuteRole(guild);
var hasDuration = duration.TotalSeconds > 0;
if (role != null) {
@@ -84,30 +56,30 @@ public class MuteCommand : Command {
await toMute.RemoveRoleAsync(role);
rolesRemoved.Add(userRole.Id);
} catch (HttpException e) {
- Warn(string.Format(Messages.RoleRemovalFailed, $"<@&{userRole}>", Utils.Wrap(e.Reason)));
+ cmd.Reply(string.Format(Messages.RoleRemovalFailed, $"<@&{userRole}>", Utils.Wrap(e.Reason)),
+ ":warning: ");
}
Boyfriend.GetRemovedRoles(guild.Id).Add(toMute.Id, rolesRemoved.AsReadOnly());
- CommandHandler.ConfigWriteScheduled = true;
-
- if (hasDuration) {
- var copy = duration;
- var _ = async () => {
- await Task.Delay(copy);
- await UnmuteCommand.UnmuteMember(guild, guild.CurrentUser, toMute, Messages.PunishmentExpired);
- };
- }
+ cmd.ConfigWriteScheduled = true;
}
await toMute.AddRoleAsync(role, requestOptions);
+
+ if (hasDuration) {
+ var _ = async () => {
+ await Task.Delay(duration);
+ await UnmuteCommand.UnmuteMember(cmd, toMute, Messages.PunishmentExpired);
+ };
+ }
} else {
if (!hasDuration || duration.TotalDays > 28) {
- Error(Messages.DurationRequiredForTimeOuts, false);
+ cmd.Reply(Messages.DurationRequiredForTimeOuts, ":x: ");
return;
}
if (toMute.IsBot) {
- Error(Messages.CannotTimeOutBot, false);
+ cmd.Reply(Messages.CannotTimeOutBot, ":x: ");
return;
}
@@ -115,9 +87,9 @@ public class MuteCommand : Command {
}
var feedback = string.Format(Messages.FeedbackMemberMuted, toMute.Mention,
- Utils.GetHumanizedTimeOffset(ref duration),
+ Utils.GetHumanizedTimeOffset(duration),
Utils.Wrap(reason));
- Success(feedback, author.Mention, false, false);
- await Utils.SendFeedback(feedback, guild.Id, author.Mention, true);
+ cmd.Reply(feedback, ":mute: ");
+ cmd.Audit(feedback);
}
-}
+}
\ No newline at end of file
diff --git a/Boyfriend/Commands/PingCommand.cs b/Boyfriend/Commands/PingCommand.cs
index c5189e4..4034f96 100644
--- a/Boyfriend/Commands/PingCommand.cs
+++ b/Boyfriend/Commands/PingCommand.cs
@@ -1,17 +1,16 @@
-using Discord.Commands;
-
-namespace Boyfriend.Commands;
+namespace Boyfriend.Commands;
public class PingCommand : Command {
- public override string[] Aliases { get; } = {"ping", "latency", "pong", "пинг", "задержка", "понг"};
- public override int ArgsLengthRequired => 0;
+ public override string[] Aliases { get; } = { "ping", "latency", "pong", "пинг", "задержка", "понг" };
- public override Task Run(SocketCommandContext context, string[] args) {
+ public override Task Run(CommandProcessor cmd, string[] args) {
var builder = Boyfriend.StringBuilder;
- builder.Append(Utils.GetBeep()).Append(Boyfriend.Client.Latency).Append(Messages.Milliseconds);
+ builder.Append(Utils.GetBeep())
+ .Append(Math.Abs(DateTimeOffset.Now.Subtract(cmd.Context.Message.Timestamp).TotalMilliseconds))
+ .Append(Messages.Milliseconds);
- Output(ref builder);
+ cmd.Reply(builder.ToString(), ":signal_strength: ");
builder.Clear();
return Task.CompletedTask;
diff --git a/Boyfriend/Commands/SettingsCommand.cs b/Boyfriend/Commands/SettingsCommand.cs
index 0a7fabc..0a5f3cf 100644
--- a/Boyfriend/Commands/SettingsCommand.cs
+++ b/Boyfriend/Commands/SettingsCommand.cs
@@ -1,23 +1,14 @@
using Discord;
-using Discord.Commands;
-using Discord.WebSocket;
namespace Boyfriend.Commands;
public class SettingsCommand : Command {
public override string[] Aliases { get; } = { "settings", "config", "настройки", "конфиг" };
- public override int ArgsLengthRequired => 0;
- public override Task Run(SocketCommandContext context, string[] args) {
- var author = (SocketGuildUser)context.User;
+ public override Task Run(CommandProcessor cmd, string[] args) {
+ if (!cmd.HasPermission(GuildPermission.ManageGuild)) return Task.CompletedTask;
- var permissionCheckResponse = CommandHandler.HasPermission(ref author, GuildPermission.ManageGuild);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return Task.CompletedTask;
- }
-
- var guild = context.Guild;
+ var guild = cmd.Context.Guild;
var config = Boyfriend.GetGuildConfig(guild.Id);
if (args.Length == 0) {
@@ -48,7 +39,7 @@ public class SettingsCommand : Command {
.AppendFormat(format, currentValue).AppendLine();
}
- Output(ref currentSettings);
+ cmd.Reply(currentSettings.ToString(), ":gear: ");
currentSettings.Clear();
return Task.CompletedTask;
}
@@ -66,19 +57,20 @@ public class SettingsCommand : Command {
}
if (!exists) {
- Error(Messages.SettingDoesntExist, false);
+ cmd.Reply(Messages.SettingDoesntExist, ":x: ");
return Task.CompletedTask;
}
- string value;
+ string? value;
if (args.Length >= 2) {
- value = Utils.JoinString(ref args, 1);
+ value = cmd.GetRemaining(args, 1, "Setting");
+ if (value == null) return Task.CompletedTask;
if (selectedSetting is "EventStartedReceivers") {
value = value.Replace(" ", "").ToLower();
if (value.StartsWith(",") || value.Count(x => x == ',') > 1 ||
(!value.Contains("interested") && !value.Contains("role"))) {
- Error(Messages.InvalidSettingValue, false);
+ cmd.Reply(Messages.InvalidSettingValue, ":x: ");
return Task.CompletedTask;
}
}
@@ -91,7 +83,7 @@ public class SettingsCommand : Command {
_ => value
};
if (!IsBool(value)) {
- Error(Messages.InvalidSettingValue, false);
+ cmd.Reply(Messages.InvalidSettingValue, ":x: ");
return Task.CompletedTask;
}
}
@@ -124,22 +116,23 @@ public class SettingsCommand : Command {
config[selectedSetting] = Boyfriend.DefaultConfig[selectedSetting];
} else {
if (value == config[selectedSetting]) {
- Error(string.Format(Messages.SettingsNothingChanged, localizedSelectedSetting, formattedValue), false);
+ cmd.Reply(string.Format(Messages.SettingsNothingChanged, localizedSelectedSetting, formattedValue),
+ ":x: ");
return Task.CompletedTask;
}
if (selectedSetting is "Lang" && value is not "ru" and not "en") {
- Error(Messages.LanguageNotSupported, false);
+ cmd.Reply(Messages.LanguageNotSupported, ":x: ");
return Task.CompletedTask;
}
if (selectedSetting.EndsWith("Channel") && guild.GetTextChannel(mention) == null) {
- Error(Messages.InvalidChannel, false);
+ cmd.Reply(Messages.InvalidChannel, ":x: ");
return Task.CompletedTask;
}
if (selectedSetting.EndsWith("Role") && guild.GetRole(mention) == null) {
- Error(Messages.InvalidRole, false);
+ cmd.Reply(Messages.InvalidRole, ":x: ");
return Task.CompletedTask;
}
@@ -153,10 +146,11 @@ public class SettingsCommand : Command {
localizedSelectedSetting = Utils.GetMessage($"Settings{selectedSetting}");
}
- CommandHandler.ConfigWriteScheduled = true;
+ cmd.ConfigWriteScheduled = true;
- Success(string.Format(Messages.FeedbackSettingsUpdated, localizedSelectedSetting, formattedValue),
- author.Mention);
+ var replyFormat = string.Format(Messages.FeedbackSettingsUpdated, localizedSelectedSetting, formattedValue);
+ cmd.Reply(replyFormat, ":control_knobs: ");
+ cmd.Audit(replyFormat, false);
return Task.CompletedTask;
}
@@ -167,4 +161,4 @@ public class SettingsCommand : Command {
private static bool IsBool(string value) {
return value is "true" or "false";
}
-}
+}
\ No newline at end of file
diff --git a/Boyfriend/Commands/UnbanCommand.cs b/Boyfriend/Commands/UnbanCommand.cs
index ac2edef..602f497 100644
--- a/Boyfriend/Commands/UnbanCommand.cs
+++ b/Boyfriend/Commands/UnbanCommand.cs
@@ -1,45 +1,27 @@
using Discord;
-using Discord.Commands;
-using Discord.WebSocket;
namespace Boyfriend.Commands;
public class UnbanCommand : Command {
public override string[] Aliases { get; } = { "unban", "разбан" };
- public override int ArgsLengthRequired => 2;
- public override async Task Run(SocketCommandContext context, string[] args) {
- var author = (SocketGuildUser)context.User;
+ public override async Task Run(CommandProcessor cmd, string[] args) {
+ if (!cmd.HasPermission(GuildPermission.BanMembers)) return;
- var permissionCheckResponse = CommandHandler.HasPermission(ref author, GuildPermission.BanMembers);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return;
- }
+ var id = cmd.GetBan(args, 0);
+ if (id == null) return;
+ var reason = cmd.GetRemaining(args, 1, "UnbanReason");
+ if (reason == null) return;
- var toUnban = Utils.ParseUser(args[0]);
-
- if (toUnban == null) {
- Error(Messages.UserDoesntExist, false);
- return;
- }
-
- var reason = Utils.JoinString(ref args, 1);
-
- await UnbanUser(context.Guild, author, toUnban, reason);
+ await UnbanUser(cmd, id.Value, reason);
}
- public static async Task UnbanUser(SocketGuild guild, SocketGuildUser author, SocketUser toUnban, string reason) {
- if (guild.GetBanAsync(toUnban.Id) == null) {
- Error(Messages.UserNotBanned, false);
- return;
- }
+ public static async Task UnbanUser(CommandProcessor cmd, ulong id, string reason) {
+ var requestOptions = Utils.GetRequestOptions($"({cmd.Context.User}) {reason}");
+ await cmd.Context.Guild.RemoveBanAsync(id, requestOptions);
- var requestOptions = Utils.GetRequestOptions($"({author}) {reason}");
- await guild.RemoveBanAsync(toUnban, requestOptions);
-
- var feedback = string.Format(Messages.FeedbackUserUnbanned, toUnban.Mention, Utils.Wrap(reason));
- Success(feedback, author.Mention, false, false);
- await Utils.SendFeedback(feedback, guild.Id, author.Mention, true);
+ var feedback = string.Format(Messages.FeedbackUserUnbanned, $"<@{id.ToString()}>", Utils.Wrap(reason));
+ cmd.Reply(feedback);
+ cmd.Audit(feedback);
}
}
\ No newline at end of file
diff --git a/Boyfriend/Commands/UnmuteCommand.cs b/Boyfriend/Commands/UnmuteCommand.cs
index a5e8d76..f5de6ed 100644
--- a/Boyfriend/Commands/UnmuteCommand.cs
+++ b/Boyfriend/Commands/UnmuteCommand.cs
@@ -1,59 +1,39 @@
using Discord;
-using Discord.Commands;
using Discord.WebSocket;
namespace Boyfriend.Commands;
public class UnmuteCommand : Command {
public override string[] Aliases { get; } = { "unmute", "размут" };
- public override int ArgsLengthRequired => 2;
- public override async Task Run(SocketCommandContext context, string[] args) {
- var author = (SocketGuildUser)context.User;
+ public override async Task Run(CommandProcessor cmd, string[] args) {
+ if (!cmd.HasPermission(GuildPermission.ModerateMembers)) return;
- var permissionCheckResponse = CommandHandler.HasPermission(ref author, GuildPermission.ModerateMembers);
- if (permissionCheckResponse is not "") {
- Error(permissionCheckResponse, true);
- return;
- }
-
- var toUnmute = Utils.ParseMember(context.Guild, args[0]);
-
- if (toUnmute == null) {
- Error(Messages.UserDoesntExist, false);
- return;
- }
-
- var interactionCheckResponse = CommandHandler.CanInteract(ref author, ref toUnmute);
- if (interactionCheckResponse is not "") {
- Error(interactionCheckResponse, true);
- return;
- }
-
- var reason = Utils.JoinString(ref args, 1);
- await UnmuteMember(context.Guild, author, toUnmute, reason);
+ var toUnmute = cmd.GetMember(args, 0, "ToUnmute");
+ var reason = cmd.GetRemaining(args, 1, "UnmuteReason");
+ if (toUnmute == null || reason == null || !cmd.CanInteractWith(toUnmute, "Unmute")) return;
+ await UnmuteMember(cmd, toUnmute, reason);
}
- public static async Task UnmuteMember(SocketGuild guild, SocketGuildUser author, SocketGuildUser toUnmute,
+ public static async Task UnmuteMember(CommandProcessor cmd, SocketGuildUser toUnmute,
string reason) {
- var requestOptions = Utils.GetRequestOptions($"({author}) {reason}");
- var role = Utils.GetMuteRole(ref guild);
+ var requestOptions = Utils.GetRequestOptions($"({cmd.Context.User}) {reason}");
+ var role = Utils.GetMuteRole(cmd.Context.Guild);
if (role != null && toUnmute.Roles.Contains(role)) {
- var rolesRemoved = Boyfriend.GetRemovedRoles(guild.Id);
+ var rolesRemoved = Boyfriend.GetRemovedRoles(cmd.Context.Guild.Id);
if (rolesRemoved.ContainsKey(toUnmute.Id)) {
await toUnmute.AddRolesAsync(rolesRemoved[toUnmute.Id]);
rolesRemoved.Remove(toUnmute.Id);
- CommandHandler.ConfigWriteScheduled = true;
+ cmd.ConfigWriteScheduled = true;
}
await toUnmute.RemoveRoleAsync(role, requestOptions);
- }
- else {
+ } else {
if (toUnmute.TimedOutUntil == null || toUnmute.TimedOutUntil.Value.ToUnixTimeMilliseconds() <
DateTimeOffset.Now.ToUnixTimeMilliseconds()) {
- Error(Messages.MemberNotMuted, false);
+ cmd.Reply(Messages.MemberNotMuted, ":x: ");
return;
}
@@ -61,7 +41,7 @@ public class UnmuteCommand : Command {
}
var feedback = string.Format(Messages.FeedbackMemberUnmuted, toUnmute.Mention, Utils.Wrap(reason));
- Success(feedback, author.Mention, false, false);
- await Utils.SendFeedback(feedback, guild.Id, author.Mention, true);
+ cmd.Reply(feedback, ":loud_sound: ");
+ cmd.Audit(feedback);
}
}
\ No newline at end of file
diff --git a/Boyfriend/EventHandler.cs b/Boyfriend/EventHandler.cs
index c4f6a99..94e75ac 100644
--- a/Boyfriend/EventHandler.cs
+++ b/Boyfriend/EventHandler.cs
@@ -64,7 +64,7 @@ public class EventHandler {
if ((message.MentionedUsers.Count > 3 || message.MentionedRoles.Count > 2) &&
!user.GuildPermissions.MentionEveryone) {
- await BanCommand.BanUser(guild, guild.CurrentUser, user, TimeSpan.FromMilliseconds(-1),
+ await BanCommand.BanUser(new CommandProcessor(message), user, TimeSpan.FromMilliseconds(-1),
Messages.AutobanReason);
return;
}
@@ -83,7 +83,7 @@ public class EventHandler {
(message.Content.Contains(prev) || message.Content.Contains(prevFailsafe))))
return;
- _ = CommandHandler.HandleCommand(message);
+ _ = new CommandProcessor(message).HandleCommand();
}
private static async Task MessageUpdatedEvent(Cacheable messageCached, SocketMessage messageSocket,
@@ -176,4 +176,4 @@ public class EventHandler {
await channel.SendMessageAsync(string.Format(Messages.EventCompleted, Utils.Wrap(scheduledEvent.Name),
Utils.Wrap(scheduledEvent.StartTime.Subtract(DateTimeOffset.Now).Negate().ToString())));
}
-}
+}
\ No newline at end of file
diff --git a/Boyfriend/Messages.Designer.cs b/Boyfriend/Messages.Designer.cs
index 3b588bf..ad39dc1 100644
--- a/Boyfriend/Messages.Designer.cs
+++ b/Boyfriend/Messages.Designer.cs
@@ -95,6 +95,87 @@ namespace Boyfriend {
}
}
+ ///
+ /// Looks up a localized string similar to I cannot ban users from this guild!.
+ ///
+ internal static string BotCannotBanMembers {
+ get {
+ return ResourceManager.GetString("BotCannotBanMembers", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot ban this user!.
+ ///
+ internal static string BotCannotBanTarget {
+ get {
+ return ResourceManager.GetString("BotCannotBanTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot kick members from this guild!.
+ ///
+ internal static string BotCannotKickMembers {
+ get {
+ return ResourceManager.GetString("BotCannotKickMembers", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot kick this member!.
+ ///
+ internal static string BotCannotKickTarget {
+ get {
+ return ResourceManager.GetString("BotCannotKickTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot manage this guild!.
+ ///
+ internal static string BotCannotManageGuild {
+ get {
+ return ResourceManager.GetString("BotCannotManageGuild", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot manage messages in this guild!.
+ ///
+ internal static string BotCannotManageMessages {
+ get {
+ return ResourceManager.GetString("BotCannotManageMessages", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot moderate members in this guild!.
+ ///
+ internal static string BotCannotModerateMembers {
+ get {
+ return ResourceManager.GetString("BotCannotModerateMembers", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot mute this member!.
+ ///
+ internal static string BotCannotMuteTarget {
+ get {
+ return ResourceManager.GetString("BotCannotMuteTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to I cannot unmute this member!.
+ ///
+ internal static string BotCannotUnmuteTarget {
+ get {
+ return ResourceManager.GetString("BotCannotUnmuteTarget", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Deleted message from {0} in channel {1}: {2}.
///
@@ -132,7 +213,16 @@ namespace Boyfriend {
}
///
- /// Looks up a localized string similar to Too many messages specified!.
+ /// Looks up a localized string similar to You need to specify an integer from {0} to {1} instead of {2}!.
+ ///
+ internal static string ClearAmountInvalid {
+ get {
+ return ResourceManager.GetString("ClearAmountInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You specified more than {0} messages!.
///
internal static string ClearAmountTooLarge {
get {
@@ -141,20 +231,11 @@ namespace Boyfriend {
}
///
- /// Looks up a localized string similar to Invalid message amount specified!.
+ /// Looks up a localized string similar to You specified less than {0} messages!.
///
- internal static string ClearInvalidAmountSpecified {
+ internal static string ClearAmountTooSmall {
get {
- return ResourceManager.GetString("ClearInvalidAmountSpecified", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Negative message amount specified!.
- ///
- internal static string ClearNegativeAmount {
- get {
- return ResourceManager.GetString("ClearNegativeAmount", resourceCulture);
+ return ResourceManager.GetString("ClearAmountTooSmall", resourceCulture);
}
}
@@ -266,15 +347,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to Couldn't find guild by message!.
- ///
- internal static string CouldntFindGuildByChannel {
- get {
- return ResourceManager.GetString("CouldntFindGuildByChannel", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Current settings:.
///
@@ -293,15 +365,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to I couldn't parse the specified duration! One of the components could be outside it's valid range (e.g. `24h` or `60m`).
- ///
- internal static string DurationParseFailed {
- get {
- return ResourceManager.GetString("DurationParseFailed", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to I cannot mute someone for more than 28 days using timeouts! Either specify a duration shorter than 28 days, or set a mute role in settings.
///
@@ -428,60 +491,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to Members are in different guilds!.
- ///
- internal static string InteractionsDifferentGuilds {
- get {
- return ResourceManager.GetString("InteractionsDifferentGuilds", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to I cannot interact with this member!.
- ///
- internal static string InteractionsFailedBot {
- get {
- return ResourceManager.GetString("InteractionsFailedBot", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to You cannot interact with this member!.
- ///
- internal static string InteractionsFailedUser {
- get {
- return ResourceManager.GetString("InteractionsFailedUser", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to You cannot interact with me!.
- ///
- internal static string InteractionsMe {
- get {
- return ResourceManager.GetString("InteractionsMe", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to You cannot interact with guild owner!.
- ///
- internal static string InteractionsOwner {
- get {
- return ResourceManager.GetString("InteractionsOwner", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to You cannot interact with yourself!.
- ///
- internal static string InteractionsYourself {
- get {
- return ResourceManager.GetString("InteractionsYourself", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to This channel does not exist!.
///
@@ -491,6 +500,15 @@ namespace Boyfriend {
}
}
+ ///
+ /// Looks up a localized string similar to You need to specify a guild member instead of {0}!.
+ ///
+ internal static string InvalidMember {
+ get {
+ return ResourceManager.GetString("InvalidMember", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to This role does not exist!.
///
@@ -509,6 +527,15 @@ namespace Boyfriend {
}
}
+ ///
+ /// Looks up a localized string similar to You need to specify a user instead of {0}!.
+ ///
+ internal static string InvalidUser {
+ get {
+ return ResourceManager.GetString("InvalidUser", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Language not supported!.
///
@@ -536,15 +563,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to {0} unmuted {1} for {2}.
- ///
- internal static string MemberUnmuted {
- get {
- return ResourceManager.GetString("MemberUnmuted", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to ms.
///
@@ -554,6 +572,87 @@ namespace Boyfriend {
}
}
+ ///
+ /// Looks up a localized string similar to You need to specify a reason to ban this user!.
+ ///
+ internal static string MissingBanReason {
+ get {
+ return ResourceManager.GetString("MissingBanReason", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a reason to kick this member!.
+ ///
+ internal static string MissingKickReason {
+ get {
+ return ResourceManager.GetString("MissingKickReason", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a guild member!.
+ ///
+ internal static string MissingMember {
+ get {
+ return ResourceManager.GetString("MissingMember", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a reason to mute this member!.
+ ///
+ internal static string MissingMuteReason {
+ get {
+ return ResourceManager.GetString("MissingMuteReason", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify an integer from {0} to {1}!.
+ ///
+ internal static string MissingNumber {
+ get {
+ return ResourceManager.GetString("MissingNumber", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a setting to change!.
+ ///
+ internal static string MissingSetting {
+ get {
+ return ResourceManager.GetString("MissingSetting", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a reason to unban this user!.
+ ///
+ internal static string MissingUnbanReason {
+ get {
+ return ResourceManager.GetString("MissingUnbanReason", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a reason for unmute this member!.
+ ///
+ internal static string MissingUnmuteReason {
+ get {
+ return ResourceManager.GetString("MissingUnmuteReason", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You need to specify a user!.
+ ///
+ internal static string MissingUser {
+ get {
+ return ResourceManager.GetString("MissingUser", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to No.
///
@@ -563,15 +662,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to Not enough arguments! Needed: {0}, provided: {1}.
- ///
- internal static string NotEnoughArguments {
- get {
- return ResourceManager.GetString("NotEnoughArguments", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Punishment expired.
///
@@ -590,15 +680,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to You must specify a reason!.
- ///
- internal static string ReasonRequired {
- get {
- return ResourceManager.GetString("ReasonRequired", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Not specified.
///
@@ -807,34 +888,196 @@ namespace Boyfriend {
}
///
- /// Looks up a localized string similar to Message deleted in {0}, but I forgot what was there.
+ /// Looks up a localized string similar to You cannot ban me!.
///
- internal static string UncachedMessageDeleted {
+ internal static string UserCannotBanBot {
get {
- return ResourceManager.GetString("UncachedMessageDeleted", resourceCulture);
+ return ResourceManager.GetString("UserCannotBanBot", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Message edited from {0} in channel {1}, but I forgot what was there before the edit: {2}.
+ /// Looks up a localized string similar to You cannot ban users from this guild!.
///
- internal static string UncachedMessageEdited {
+ internal static string UserCannotBanMembers {
get {
- return ResourceManager.GetString("UncachedMessageEdited", resourceCulture);
+ return ResourceManager.GetString("UserCannotBanMembers", resourceCulture);
}
}
///
- /// Looks up a localized string similar to That user doesn't exist!.
+ /// Looks up a localized string similar to You cannot ban the owner of this guild!.
///
- internal static string UserDoesntExist {
+ internal static string UserCannotBanOwner {
get {
- return ResourceManager.GetString("UserDoesntExist", resourceCulture);
+ return ResourceManager.GetString("UserCannotBanOwner", resourceCulture);
}
}
///
- /// Looks up a localized string similar to User not banned!.
+ /// Looks up a localized string similar to You cannot ban this user!.
+ ///
+ internal static string UserCannotBanTarget {
+ get {
+ return ResourceManager.GetString("UserCannotBanTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot ban yourself!.
+ ///
+ internal static string UserCannotBanThemselves {
+ get {
+ return ResourceManager.GetString("UserCannotBanThemselves", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot kick me!.
+ ///
+ internal static string UserCannotKickBot {
+ get {
+ return ResourceManager.GetString("UserCannotKickBot", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot kick members from this guild!.
+ ///
+ internal static string UserCannotKickMembers {
+ get {
+ return ResourceManager.GetString("UserCannotKickMembers", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot kick the owner of this guild!.
+ ///
+ internal static string UserCannotKickOwner {
+ get {
+ return ResourceManager.GetString("UserCannotKickOwner", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot kick this member!.
+ ///
+ internal static string UserCannotKickTarget {
+ get {
+ return ResourceManager.GetString("UserCannotKickTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot kick yourself!.
+ ///
+ internal static string UserCannotKickThemselves {
+ get {
+ return ResourceManager.GetString("UserCannotKickThemselves", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot manage this guild!.
+ ///
+ internal static string UserCannotManageGuild {
+ get {
+ return ResourceManager.GetString("UserCannotManageGuild", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot manage messages in this guild!.
+ ///
+ internal static string UserCannotManageMessages {
+ get {
+ return ResourceManager.GetString("UserCannotManageMessages", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot moderate members in this guild!.
+ ///
+ internal static string UserCannotModerateMembers {
+ get {
+ return ResourceManager.GetString("UserCannotModerateMembers", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot mute me!.
+ ///
+ internal static string UserCannotMuteBot {
+ get {
+ return ResourceManager.GetString("UserCannotMuteBot", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot mute the owner of this guild!.
+ ///
+ internal static string UserCannotMuteOwner {
+ get {
+ return ResourceManager.GetString("UserCannotMuteOwner", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot mute this member!.
+ ///
+ internal static string UserCannotMuteTarget {
+ get {
+ return ResourceManager.GetString("UserCannotMuteTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot mute yourself!.
+ ///
+ internal static string UserCannotMuteThemselves {
+ get {
+ return ResourceManager.GetString("UserCannotMuteThemselves", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ....
+ ///
+ internal static string UserCannotUnmuteBot {
+ get {
+ return ResourceManager.GetString("UserCannotUnmuteBot", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You don't need to unmute the owner of this guild!.
+ ///
+ internal static string UserCannotUnmuteOwner {
+ get {
+ return ResourceManager.GetString("UserCannotUnmuteOwner", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You cannot unmute this user!.
+ ///
+ internal static string UserCannotUnmuteTarget {
+ get {
+ return ResourceManager.GetString("UserCannotUnmuteTarget", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You are muted!.
+ ///
+ internal static string UserCannotUnmuteThemselves {
+ get {
+ return ResourceManager.GetString("UserCannotUnmuteThemselves", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to This user is not banned!.
///
internal static string UserNotBanned {
get {
@@ -851,15 +1094,6 @@ namespace Boyfriend {
}
}
- ///
- /// Looks up a localized string similar to {0} unbanned {1} for {2}.
- ///
- internal static string UserUnbanned {
- get {
- return ResourceManager.GetString("UserUnbanned", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Yes.
///
diff --git a/Boyfriend/Messages.resx b/Boyfriend/Messages.resx
index 4d1685d..88ab26c 100644
--- a/Boyfriend/Messages.resx
+++ b/Boyfriend/Messages.resx
@@ -24,24 +24,15 @@
PublicKeyToken=b77a5c561934e089
-
- Couldn't find guild by message!
-
{0}I'm ready! (C#)
-
- Message deleted in {0}, but I forgot what was there
-
Deleted message from {0} in channel {1}: {2}
Too many mentions in 1 message
-
- Message edited from {0} in channel {1}, but I forgot what was there before the edit: {2}
-
Edited message in channel {0}: {1} -> {2}
@@ -63,35 +54,17 @@
You do not have permission to execute this command!
-
- Members are in different guilds!
-
-
- You cannot interact with guild owner!
-
-
- You cannot interact with yourself!
-
-
- You cannot interact with me!
-
-
- You cannot interact with this member!
-
-
- I cannot interact with this member!
-
You were banned by {0} in guild {1} for {2}
Punishment expired
-
- Negative message amount specified!
+
+ You specified less than {0} messages!
- Too many messages specified!
+ You specified more than {0} messages!
Command help:
@@ -148,7 +121,7 @@
No
- User not banned!
+ This user is not banned!
Member not muted!
@@ -156,20 +129,11 @@
Someone removed the mute role manually! I added back all roles that I removed during the mute
-
- {0} unmuted {1} for {2}
-
-
- {0} unbanned {1} for {2}
-
Welcome message
-
- Not enough arguments! Needed: {0}, provided: {1}
-
-
- Invalid message amount specified!
+
+ You need to specify an integer from {0} to {1} instead of {2}!
Banned {0} for{1}: {2}
@@ -192,9 +156,6 @@
This channel does not exist!
-
- I couldn't parse the specified duration! One of the components could be outside it's valid range (e.g. `24h` or `60m`)
-
I couldn't remove role {0} because of an error! {1}
@@ -237,9 +198,6 @@
Event {0} has completed! Duration: {1}
-
- That user doesn't exist!
-
*[{0}: {1}]*
@@ -297,7 +255,127 @@
Unmutes a member
-
- You must specify a reason!
+
+ You need to specify an integer from {0} to {1}!
+
+
+ You need to specify a user!
+
+
+ You need to specify a user instead of {0}!
+
+
+ You need to specify a guild member!
+
+
+ You need to specify a guild member instead of {0}!
+
+
+ You cannot ban users from this guild!
+
+
+ You cannot manage messages in this guild!
+
+
+ You cannot kick members from this guild!
+
+
+ You cannot moderate members in this guild!
+
+
+ You cannot manage this guild!
+
+
+ I cannot ban users from this guild!
+
+
+ I cannot manage messages in this guild!
+
+
+ I cannot kick members from this guild!
+
+
+ I cannot moderate members in this guild!
+
+
+ I cannot manage this guild!
+
+
+ You need to specify a reason to ban this user!
+
+
+ You need to specify a reason to kick this member!
+
+
+ You need to specify a reason to mute this member!
+
+
+ You need to specify a reason to unban this user!
+
+
+ You need to specify a reason for unmute this member!
+
+
+ You need to specify a setting to change!
+
+
+ You cannot ban the owner of this guild!
+
+
+ You cannot ban yourself!
+
+
+ You cannot ban me!
+
+
+ I cannot ban this user!
+
+
+ You cannot ban this user!
+
+
+ You cannot kick the owner of this guild!
+
+
+ You cannot kick yourself!
+
+
+ You cannot kick me!
+
+
+ I cannot kick this member!
+
+
+ You cannot kick this member!
+
+
+ You cannot mute the owner of this guild!
+
+
+ You cannot mute yourself!
+
+
+ You cannot mute me!
+
+
+ I cannot mute this member!
+
+
+ You cannot mute this member!
+
+
+ You don't need to unmute the owner of this guild!
+
+
+ You are muted!
+
+
+ ...
+
+
+ I cannot unmute this member!
+
+
+ You cannot unmute this user!
diff --git a/Boyfriend/Messages.ru.resx b/Boyfriend/Messages.ru.resx
index 0c10ab5..78359d6 100644
--- a/Boyfriend/Messages.ru.resx
+++ b/Boyfriend/Messages.ru.resx
@@ -15,24 +15,15 @@
PublicKeyToken=b77a5c561934e089
-
- Не удалось найти сервер по каналу!
-
{0}Я запустился! (C#)
-
- Удалено сообщение в канале {0}, но я забыл что там было
-
Удалено сообщение от {0} в канале {1}: {2}
Слишком много упоминаний в одном сообщении
-
- Отредактировано сообщение от {0} в канале {1}, но я забыл что там было до редактирования: {2}
-
Отредактировано сообщение в канале {0}: {1} -> {2}
@@ -54,35 +45,17 @@
У тебя недостаточно прав для выполнения этой команды!
-
- Участники находятся в разных гильдиях!
-
-
- Ты не можешь взаимодействовать с владельцем сервера!
-
-
- Ты не можешь взаимодействовать с самим собой!
-
-
- Ты не можешь со мной взаимодействовать!
-
-
- Ты не можешь взаимодействовать с этим участником!
-
-
- Я не могу взаимодействовать с этим участником!
-
Тебя забанил {0} на сервере {1} за {2}
Время наказания истекло
-
- Указано отрицательное количество сообщений!
+
+ Указано менее {0} сообщений!
- Указано слишком много сообщений!
+ Указано более {0} сообщений!
Справка по командам:
@@ -136,7 +109,7 @@
Нет
- Пользователь не забанен!
+ Этот пользователь не забанен!
Участник не заглушен!
@@ -144,20 +117,11 @@
Кто-то убрал роль мута самостоятельно! Я вернул все роли, которые забрал при муте
-
- {0} возвращает из мута {1} за {2}
-
-
- {0} возвращает из бана {1} за {2}
-
Приветствие
-
- Недостаточно аргументов! Требуется: {0}, указано: {1}
-
-
- Указано неверное количество сообщений!
+
+ Надо указать целое число от {0} до {1} вместо {2}!
Забанен {0} на{1}: {2}
@@ -180,9 +144,6 @@
Этот канал не существует!
-
- Мне не удалось обработать продолжительность! Один из компонентов может быть за пределами допустимого диапазона (например, `24ч` или `60м`)
-
Я не смог забрать роль {0} в связи с ошибкой! {1}
@@ -228,9 +189,6 @@
Событие {0} завершено! Продолжительность: {1}
-
- Такого пользователя не существует!
-
*[{0}: {1}]*
@@ -288,7 +246,127 @@
Разглушает участника
-
- Требуется указать причину!
+
+ Надо указать целое число от {0} до {1}!
+
+
+ Надо указать пользователя!
+
+
+ Надо указать пользователя вместо {0}!
+
+
+ Надо указать участника сервера!
+
+
+ Надо указать участника сервера вместо {0}!
+
+
+ Ты не можешь банить пользователей на этом сервере!
+
+
+ Ты не можешь управлять сообщениями этого сервера!
+
+
+ Ты не можешь выгонять участников с этого сервера!
+
+
+ Ты не можешь модерировать участников этого сервера!
+
+
+ Ты не можешь настраивать этот сервер!
+
+
+ Я не могу банить пользователей на этом сервере!
+
+
+ Я не могу управлять сообщениями этого сервера!
+
+
+ Я не могу выгонять участников с этого сервера!
+
+
+ Я не могу модерировать участников этого сервера!
+
+
+ Я не могу настраивать этот сервер!
+
+
+ Надо указать причину для бана этого участника!
+
+
+ Надо указать причину для кика этого участника!
+
+
+ Надо указать причину для мута этого участника!
+
+
+ Надо указать настройку, которую нужно изменить!
+
+
+ Надо указать причину для разбана этого пользователя!
+
+
+ Надо указать причину для размута этого участника!
+
+
+ Ты не можешь меня забанить!
+
+
+ Ты не можешь забанить владельца этого сервера!
+
+
+ Ты не можешь забанить этого участника!
+
+
+ Ты не можешь себя забанить!
+
+
+ Я не могу забанить этого пользователя!
+
+
+ Ты не можешь выгнать владельца этого сервера!
+
+
+ Ты не можешь себя выгнать!
+
+
+ Ты не можешь меня выгнать!
+
+
+ Я не могу выгнать этого участника
+
+
+ Ты не можешь выгнать этого участника!
+
+
+ Ты не можешь заглушить владельца этого сервера!
+
+
+ Ты не можешь себя заглушить!
+
+
+ Ты не можешь заглушить меня!
+
+
+ Я не могу заглушить этого пользователя!
+
+
+ Ты не можешь заглушить этого участника!
+
+
+ Тебе не надо возвращать из мута владельца этого сервера!
+
+
+ Ты заглушен!
+
+
+ ...
+
+
+ Ты не можешь вернуть из мута этого пользователя!
+
+
+ Я не могу вернуть из мута этого пользователя!
diff --git a/Boyfriend/Utils.cs b/Boyfriend/Utils.cs
index 213196e..3802ceb 100644
--- a/Boyfriend/Utils.cs
+++ b/Boyfriend/Utils.cs
@@ -1,5 +1,6 @@
using System.Globalization;
using System.Reflection;
+using System.Text;
using System.Text.RegularExpressions;
using Discord;
using Discord.Net;
@@ -65,7 +66,7 @@ public static class Utils {
}
}
- public static SocketRole? GetMuteRole(ref SocketGuild guild) {
+ public static SocketRole? GetMuteRole(SocketGuild guild) {
var id = ulong.Parse(Boyfriend.GetGuildConfig(guild.Id)["MuteRole"]);
if (MuteRoleCache.ContainsKey(id)) return MuteRoleCache[id];
SocketRole? role = null;
@@ -90,41 +91,6 @@ public static class Utils {
await channel.SendMessageAsync(text, false, null, null, allowRoles ? AllowRoles : AllowedMentions.None);
}
- public static TimeSpan? GetTimeSpan(ref string from) {
- var chars = from.AsSpan();
- var numberBuilder = Boyfriend.StringBuilder;
- int days = 0, hours = 0, minutes = 0, seconds = 0;
- foreach (var c in chars)
- if (char.IsDigit(c)) { numberBuilder.Append(c); } else {
- if (numberBuilder.Length == 0) return null;
- switch (c) {
- case 'd' or 'D' or 'д' or 'Д':
- days += int.Parse(numberBuilder.ToString());
- numberBuilder.Clear();
- break;
- case 'h' or 'H' or 'ч' or 'Ч':
- hours += int.Parse(numberBuilder.ToString());
- numberBuilder.Clear();
- break;
- case 'm' or 'M' or 'м' or 'М':
- minutes += int.Parse(numberBuilder.ToString());
- numberBuilder.Clear();
- break;
- case 's' or 'S' or 'с' or 'С':
- seconds += int.Parse(numberBuilder.ToString());
- numberBuilder.Clear();
- break;
- default: return null;
- }
- }
-
- numberBuilder.Clear();
- return new TimeSpan(days, hours, minutes, seconds);
- }
-
- public static string JoinString(ref string[] args, int startIndex) {
- return string.Join(" ", args, startIndex, args.Length - startIndex);
- }
public static RequestOptions GetRequestOptions(string reason) {
var options = RequestOptions.Default;
@@ -139,7 +105,12 @@ public static class Utils {
var toReturn =
typeof(Messages).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null)
- ?.ToString()! ?? throw new Exception($"Could not find localized property: {propertyName}");
+ ?.ToString();
+ if (toReturn == null) {
+ Console.WriteLine($@"Could not find localized property: {propertyName}");
+ return name;
+ }
+
ReflectionMessageCache.Add(name, toReturn);
return toReturn;
}
@@ -154,13 +125,7 @@ public static class Utils {
await SilentSendAsync(systemChannel, toSend);
}
- public static void StackFeedback(ref string feedback, ref string mention, bool isPublic) {
- var toAppend = string.Format(Messages.FeedbackFormat, mention, feedback);
- CommandHandler.StackedPrivateFeedback.AppendLine(toAppend);
- if (isPublic) CommandHandler.StackedPublicFeedback.AppendLine(toAppend);
- }
-
- public static string GetHumanizedTimeOffset(ref TimeSpan span) {
+ public static string GetHumanizedTimeOffset(TimeSpan span) {
return span.TotalSeconds > 0
? $" {span.Humanize(2, minUnit: TimeUnit.Second, maxUnit: TimeUnit.Month, culture: Messages.Culture)}"
: Messages.Ever;
@@ -169,4 +134,23 @@ public static class Utils {
public static void SetCurrentLanguage(ulong guildId) {
Messages.Culture = CultureInfoCache[Boyfriend.GetGuildConfig(guildId)["Lang"]];
}
-}
+
+ public static void SafeAppendToBuilder(StringBuilder appendTo, string appendWhat, SocketTextChannel? channel) {
+ if (channel == null) return;
+ if (appendTo.Length + appendWhat.Length > 2000) {
+ _ = SilentSendAsync(channel, appendTo.ToString());
+ appendTo.Clear();
+ }
+
+ appendTo.AppendLine(appendWhat);
+ }
+
+ public static void SafeAppendToBuilder(StringBuilder appendTo, string appendWhat, SocketUserMessage message) {
+ if (appendTo.Length + appendWhat.Length > 2000) {
+ _ = message.ReplyAsync(appendTo.ToString(), false, null, AllowedMentions.None);
+ appendTo.Clear();
+ }
+
+ appendTo.AppendLine(appendWhat);
+ }
+}
\ No newline at end of file