From 868b6bcaa7ae15017f427020b112285e69345028 Mon Sep 17 00:00:00 2001 From: l1ttleO Date: Mon, 21 Feb 2022 22:08:55 +0500 Subject: [PATCH] time-out failsafes and new warnings rewrote setting values in SettingsCommand.cs fixed a bug with message edited notification on mobile fixed an exploit with WrapInline where you could escape the code block by simply using ` moved a few things in MuteCommand.cs cleaned up code updated library to 3.3.2 --- Boyfriend/Boyfriend.cs | 17 +-- Boyfriend/Boyfriend.csproj | 2 +- Boyfriend/Commands/BanCommand.cs | 20 ++-- Boyfriend/Commands/Command.cs | 5 +- Boyfriend/Commands/MuteCommand.cs | 55 +++++----- Boyfriend/Commands/SettingsCommand.cs | 150 ++++++++++---------------- Boyfriend/EventHandler.cs | 35 +++--- Boyfriend/GuildConfig.cs | 11 +- Boyfriend/Messages.Designer.cs | 137 ++++++++--------------- Boyfriend/Messages.resx | 59 ++++------ Boyfriend/Messages.ru.resx | 59 ++++------ Boyfriend/Utils.cs | 15 +-- 12 files changed, 220 insertions(+), 345 deletions(-) diff --git a/Boyfriend/Boyfriend.cs b/Boyfriend/Boyfriend.cs index 1793c3e..96d4df8 100644 --- a/Boyfriend/Boyfriend.cs +++ b/Boyfriend/Boyfriend.cs @@ -1,7 +1,7 @@ using System.Globalization; -using Newtonsoft.Json; using Discord; using Discord.WebSocket; +using Newtonsoft.Json; namespace Boyfriend; @@ -56,20 +56,11 @@ public static class Boyfriend { } } - public static void ResetGuildConfig(IGuild guild) { - GuildConfigDictionary.Remove(guild.Id); - - var config = new GuildConfig(guild.Id); - config.Validate(); - - GuildConfigDictionary.Add(guild.Id, config); - } - public static GuildConfig GetGuildConfig(IGuild guild) { Messages.Culture = new CultureInfo("ru"); - var config = GuildConfigDictionary.ContainsKey(guild.Id) ? GuildConfigDictionary[guild.Id] : - new GuildConfig(guild.Id); + var config = GuildConfigDictionary.ContainsKey(guild.Id) ? GuildConfigDictionary[guild.Id] + : new GuildConfig(guild.Id); config.Validate(); return config; @@ -82,4 +73,4 @@ public static class Boyfriend { throw new Exception(Messages.CouldntFindGuildByChannel); } -} +} \ No newline at end of file diff --git a/Boyfriend/Boyfriend.csproj b/Boyfriend/Boyfriend.csproj index eaa313b..cd969e0 100644 --- a/Boyfriend/Boyfriend.csproj +++ b/Boyfriend/Boyfriend.csproj @@ -15,7 +15,7 @@ - + diff --git a/Boyfriend/Commands/BanCommand.cs b/Boyfriend/Commands/BanCommand.cs index 05a18f0..60e945f 100644 --- a/Boyfriend/Commands/BanCommand.cs +++ b/Boyfriend/Commands/BanCommand.cs @@ -16,6 +16,7 @@ public class BanCommand : Command { duration = Utils.GetTimeSpan(args[1]); reason = Utils.JoinString(args, 2); } catch (Exception e) when (e is ArgumentNullException or FormatException or OverflowException) { + await Warn(context.Channel as ITextChannel, Messages.DurationParseFailed); duration = TimeSpan.FromMilliseconds(-1); } @@ -28,10 +29,8 @@ public class BanCommand : Command { var authorMention = author.Mention; var guildBanMessage = $"({Utils.GetNameAndDiscrim(author)}) {reason}"; var memberToBan = await guild.GetUserAsync(toBan.Id); - var expiresIn = duration.TotalSeconds > 0 - ? string.Format(Messages.PunishmentExpiresIn, Environment.NewLine, - DateTimeOffset.Now.ToUnixTimeSeconds() + duration.TotalSeconds) - : ""; + var expiresIn = duration.TotalSeconds > 0 ? string.Format(Messages.PunishmentExpiresIn, Environment.NewLine, + DateTimeOffset.Now.ToUnixTimeSeconds() + duration.TotalSeconds) : ""; var notification = string.Format(Messages.UserBanned, authorMention, toBan.Mention, Utils.WrapInline(reason), expiresIn); @@ -39,25 +38,24 @@ public class BanCommand : Command { if (memberToBan != null) await CommandHandler.CheckInteractions(author, memberToBan); - await Utils.SendDirectMessage(toBan, string.Format(Messages.YouWereBanned, author.Mention, guild.Name, - Utils.WrapInline(reason))); + await Utils.SendDirectMessage(toBan, + string.Format(Messages.YouWereBanned, author.Mention, guild.Name, Utils.WrapInline(reason))); await guild.AddBanAsync(toBan, 0, guildBanMessage); - await Utils.SilentSendAsync(channel, string.Format(Messages.BanResponse, toBan.Mention, - Utils.WrapInline(reason))); + await Utils.SilentSendAsync(channel, + string.Format(Messages.BanResponse, toBan.Mention, Utils.WrapInline(reason))); await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification); await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification); if (duration.TotalSeconds > 0) { - var task = new Task(async () => { + await Task.Run(async () => { await Task.Delay(duration); try { await UnbanCommand.UnbanUser(guild, null, await guild.GetCurrentUserAsync(), toBan, Messages.PunishmentExpired); } catch (ApplicationException) {} }); - task.Start(); } } @@ -72,4 +70,4 @@ public class BanCommand : Command { public override string GetSummary() { return "Банит пользователя"; } -} +} \ No newline at end of file diff --git a/Boyfriend/Commands/Command.cs b/Boyfriend/Commands/Command.cs index b90d6b0..af2c845 100644 --- a/Boyfriend/Commands/Command.cs +++ b/Boyfriend/Commands/Command.cs @@ -1,6 +1,5 @@ using Discord; using Discord.Commands; -using Discord.WebSocket; namespace Boyfriend.Commands; @@ -13,7 +12,7 @@ public abstract class Command { public abstract string GetSummary(); - protected static async Task Warn(ISocketMessageChannel channel, string warning) { - await Utils.SilentSendAsync(channel as ITextChannel, ":warning: " + warning); + protected static async Task Warn(ITextChannel? channel, string warning) { + await Utils.SilentSendAsync(channel, ":warning: " + warning); } } \ No newline at end of file diff --git a/Boyfriend/Commands/MuteCommand.cs b/Boyfriend/Commands/MuteCommand.cs index 931384e..4ad55e8 100644 --- a/Boyfriend/Commands/MuteCommand.cs +++ b/Boyfriend/Commands/MuteCommand.cs @@ -22,23 +22,22 @@ public class MuteCommand : Command { duration = Utils.GetTimeSpan(args[1]); reason = Utils.JoinString(args, 2); } catch (Exception e) when (e is ArgumentNullException or FormatException or OverflowException) { + await Warn(context.Channel as ITextChannel, Messages.DurationParseFailed); duration = TimeSpan.FromMilliseconds(-1); } if (toMute == null) throw new ApplicationException(Messages.UserNotInGuild); - if (role != null && toMute.RoleIds.Any(x => x == role.Id) || - toMute.TimedOutUntil != null && toMute.TimedOutUntil.Value.ToUnixTimeMilliseconds() - > DateTimeOffset.Now.ToUnixTimeMilliseconds()) + if (role != null && toMute.RoleIds.Any(x => x == role.Id) || toMute.TimedOutUntil != null && + toMute.TimedOutUntil.Value.ToUnixTimeMilliseconds() > DateTimeOffset.Now.ToUnixTimeMilliseconds()) throw new ApplicationException(Messages.MemberAlreadyMuted); if (rolesRemoved.ContainsKey(toMute.Id)) { foreach (var roleId in rolesRemoved[toMute.Id]) await toMute.AddRoleAsync(roleId); rolesRemoved.Remove(toMute.Id); await config.Save(); - await Warn(context.Channel, Messages.RolesReturned); - return; + throw new ApplicationException(Messages.RolesReturned); } await CommandHandler.CheckPermissions(author, GuildPermission.ModerateMembers, GuildPermission.ManageRoles); @@ -55,10 +54,9 @@ public class MuteCommand : Command { var config = Boyfriend.GetGuildConfig(guild); var requestOptions = Utils.GetRequestOptions($"({Utils.GetNameAndDiscrim(author)}) {reason}"); var role = Utils.GetMuteRole(guild); - var expiresIn = duration.TotalSeconds > 0 - ? string.Format(Messages.PunishmentExpiresIn, Environment.NewLine, - DateTimeOffset.Now.ToUnixTimeSeconds() + duration.TotalSeconds) - : ""; + var hasDuration = duration.TotalSeconds > 0; + var expiresIn = hasDuration ? string.Format(Messages.PunishmentExpiresIn, Environment.NewLine, + DateTimeOffset.Now.ToUnixTimeSeconds() + duration.TotalSeconds) : ""; var notification = string.Format(Messages.MemberMuted, authorMention, toMute.Mention, Utils.WrapInline(reason), expiresIn); @@ -71,31 +69,38 @@ public class MuteCommand : Command { if (roleId == role.Id) continue; await toMute.RemoveRoleAsync(roleId); rolesRemoved.Add(roleId); - } catch (HttpException) {} + } catch (HttpException e) { + await Warn(channel, + string.Format(Messages.RoleRemovalFailed, $"<@&{roleId}>", Utils.WrapInline(e.Reason))); + } } config.RolesRemovedOnMute!.Add(toMute.Id, rolesRemoved); await config.Save(); + + if (hasDuration) + await Task.Run(async () => { + await Task.Delay(duration); + try { + await UnmuteCommand.UnmuteMember(guild, null, await guild.GetCurrentUserAsync(), toMute, + Messages.PunishmentExpired); + } catch (ApplicationException) {} + }); } await toMute.AddRoleAsync(role, requestOptions); - } else + } else { + if (!hasDuration) + throw new ApplicationException(Messages.DurationRequiredForTimeOuts); + if (toMute.IsBot) + throw new ApplicationException(Messages.CannotTimeOutBot); + await toMute.SetTimeOutAsync(duration, requestOptions); - await Utils.SilentSendAsync(channel, string.Format(Messages.MuteResponse, toMute.Mention, - Utils.WrapInline(reason))); + } + await Utils.SilentSendAsync(channel, + string.Format(Messages.MuteResponse, toMute.Mention, Utils.WrapInline(reason))); await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification); await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification); - - if (role != null && duration.TotalSeconds > 0) { - var task = new Task(async () => { - await Task.Delay(duration); - try { - await UnmuteCommand.UnmuteMember(guild, null, await guild.GetCurrentUserAsync(), toMute, - Messages.PunishmentExpired); - } catch (ApplicationException) {} - }); - task.Start(); - } } public override List GetAliases() { @@ -109,4 +114,4 @@ public class MuteCommand : Command { public override string GetSummary() { return "Глушит участника"; } -} +} \ No newline at end of file diff --git a/Boyfriend/Commands/SettingsCommand.cs b/Boyfriend/Commands/SettingsCommand.cs index fd5da44..c0e189a 100644 --- a/Boyfriend/Commands/SettingsCommand.cs +++ b/Boyfriend/Commands/SettingsCommand.cs @@ -1,4 +1,4 @@ -using System.Globalization; +using System.Reflection; using Discord; using Discord.Commands; @@ -16,117 +16,83 @@ public class SettingsCommand : Command { if (args.Length == 0) { var nl = Environment.NewLine; - var adminLogChannel = guild.GetTextChannel(config.AdminLogChannel.GetValueOrDefault(0)); - var admin = adminLogChannel == null ? Messages.ChannelNotSpecified : adminLogChannel.Mention; - var botLogChannel = guild.GetTextChannel(config.BotLogChannel.GetValueOrDefault(0)); - var bot = botLogChannel == null ? Messages.ChannelNotSpecified : botLogChannel.Mention; - var muteRole = guild.GetRole(config.MuteRole.GetValueOrDefault(0)); - var mute = muteRole == null ? Messages.RoleNotSpecified : muteRole.Mention; - var defaultRole = guild.GetRole(config.DefaultRole.GetValueOrDefault(0)); - var defaultr = defaultRole == null ? Messages.RoleNotSpecified : defaultRole.Mention; + dynamic forCheck; + var adminLogChannel = (forCheck = guild.GetTextChannel(config.AdminLogChannel.GetValueOrDefault(0))) == null + ? Messages.ChannelNotSpecified : forCheck.Mention; + var botLogChannel = (forCheck = guild.GetTextChannel(config.BotLogChannel.GetValueOrDefault(0))) == null + ? Messages.ChannelNotSpecified : forCheck.Mention; + var muteRole = (forCheck = guild.GetRole(config.MuteRole.GetValueOrDefault(0))) == null + ? Messages.RoleNotSpecified : forCheck.Mention; + var defaultRole = (forCheck = guild.GetRole(config.DefaultRole.GetValueOrDefault(0))) == null + ? Messages.RoleNotSpecified : forCheck.Mention; var toSend = string.Format(Messages.CurrentSettings, nl) + string.Format(Messages.CurrentSettingsLang, config.Lang, nl) + string.Format(Messages.CurrentSettingsPrefix, config.Prefix, nl) + - string.Format(Messages.CurrentSettingsRemoveRoles, YesOrNo( - config.RemoveRolesOnMute.GetValueOrDefault(false)), nl) + - string.Format(Messages.CurrentSettingsUseSystemChannel, YesOrNo( - config.UseSystemChannel.GetValueOrDefault(true)), nl) + - string.Format(Messages.CurrentSettingsSendWelcomeMessages, YesOrNo( - config.SendWelcomeMessages.GetValueOrDefault(true)), nl) + - string.Format(Messages.CurrentSettingsReceiveStartupMessages, YesOrNo( - config.ReceiveStartupMessages.GetValueOrDefault(true)), nl) + + string.Format(Messages.CurrentSettingsRemoveRoles, + YesOrNo(config.RemoveRolesOnMute.GetValueOrDefault(false)), nl) + + string.Format(Messages.CurrentSettingsUseSystemChannel, + YesOrNo(config.UseSystemChannel.GetValueOrDefault(true)), nl) + + string.Format(Messages.CurrentSettingsSendWelcomeMessages, + YesOrNo(config.SendWelcomeMessages.GetValueOrDefault(true)), nl) + + string.Format(Messages.CurrentSettingsReceiveStartupMessages, + YesOrNo(config.ReceiveStartupMessages.GetValueOrDefault(true)), nl) + string.Format(Messages.CurrentSettingsWelcomeMessage, config.WelcomeMessage, nl) + - string.Format(Messages.CurrentSettingsDefaultRole, defaultr, nl) + - string.Format(Messages.CurrentSettingsMuteRole, mute, nl) + - string.Format(Messages.CurrentSettingsAdminLogChannel, admin, nl) + - string.Format(Messages.CurrentSettingsBotLogChannel, bot); + string.Format(Messages.CurrentSettingsDefaultRole, defaultRole, nl) + + string.Format(Messages.CurrentSettingsMuteRole, muteRole, nl) + + string.Format(Messages.CurrentSettingsAdminLogChannel, adminLogChannel, nl) + + string.Format(Messages.CurrentSettingsBotLogChannel, botLogChannel); await Utils.SilentSendAsync(context.Channel as ITextChannel ?? throw new ApplicationException(), toSend); return; } var setting = args[0].ToLower(); - var shouldDefault = false; var value = ""; if (args.Length >= 2) - value = args[1].ToLower(); - else - shouldDefault = true; + try { + value = args[1].ToLower(); + } catch (IndexOutOfRangeException) { + throw new ApplicationException(Messages.InvalidSettingValue); + } - var boolValue = ParseBool(value); - var channel = await Utils.ParseChannelNullable(value) as IGuildChannel; - var role = Utils.ParseRoleNullable(guild, value); + PropertyInfo? property = null; + foreach (var prop in typeof(GuildConfig).GetProperties()) + if (setting == prop.Name.ToLower()) + property = prop; + if (property == null || !property.CanWrite) + throw new ApplicationException(Messages.SettingDoesntExist); + var type = property.PropertyType; - switch (setting) { - case "reset": - Boyfriend.ResetGuildConfig(guild); - break; - case "lang" when value is not ("ru" or "en"): + if (value is "reset" or "default") { + property.SetValue(config, null); + } else if (type == typeof(string)) { + if (setting == "lang" && value is not ("ru" or "en")) throw new ApplicationException(Messages.LanguageNotSupported); - case "lang": - config.Lang = shouldDefault ? "ru" : value; - Messages.Culture = new CultureInfo(shouldDefault ? "ru" : value); - break; - case "prefix": - config.Prefix = shouldDefault ? "!" : value; - break; - case "removerolesonmute": - config.RemoveRolesOnMute = !shouldDefault && GetBoolValue(boolValue); - break; - case "usesystemchannel": - config.UseSystemChannel = shouldDefault || GetBoolValue(boolValue); - break; - case "sendwelcomemessages": - config.SendWelcomeMessages = shouldDefault || GetBoolValue(boolValue); - break; - case "receivestartupmessages": - config.ReceiveStartupMessages = shouldDefault || GetBoolValue(boolValue); - break; - case "welcomemessage": - config.WelcomeMessage = shouldDefault ? Messages.DefaultWelcomeMessage : value; - break; - case "defaultrole": - config.DefaultRole = shouldDefault ? 0 : GetRoleId(role); - break; - case "muterole": - config.MuteRole = shouldDefault ? 0 : GetRoleId(role); - break; - case "adminlogchannel": - config.AdminLogChannel = shouldDefault ? 0 : GetChannelId(channel); - break; - case "botlogchannel": - config.BotLogChannel = shouldDefault ? 0 : GetChannelId(channel); - break; - default: - await context.Channel.SendMessageAsync(Messages.SettingDoesntExist); - return; + property.SetValue(config, value); + } else { + try { + if (type == typeof(bool?)) + property.SetValue(config, Convert.ToBoolean(value)); + + if (type == typeof(ulong?)) { + var id = Convert.ToUInt64(value); + if (property.Name.EndsWith("Channel") && guild.GetTextChannel(id) == null) + throw new ApplicationException(Messages.InvalidChannel); + if (property.Name.EndsWith("Role") && guild.GetRole(id) == null) + throw new ApplicationException(Messages.InvalidRole); + + property.SetValue(config, id); + } + } catch (Exception e) when (e is FormatException or OverflowException) { + throw new ApplicationException(Messages.InvalidSettingValue); + } } + config.Validate(); await config.Save(); - await context.Channel.SendMessageAsync(Messages.SettingsUpdated); } - private static bool? ParseBool(string toParse) { - try { - return bool.Parse(toParse.ToLower()); - } catch (FormatException) { - return null; - } - } - - private static bool GetBoolValue(bool? from) { - return from ?? throw new ApplicationException(Messages.InvalidBoolean); - } - - private static ulong GetRoleId(IRole? role) { - return (role ?? throw new ApplicationException(Messages.InvalidRoleSpecified)).Id; - } - - private static ulong GetChannelId(IGuildChannel? channel) { - return (channel ?? throw new ApplicationException(Messages.InvalidChannelSpecified)).Id; - } - private static string YesOrNo(bool isYes) { return isYes ? Messages.Yes : Messages.No; } @@ -142,4 +108,4 @@ public class SettingsCommand : Command { public override string GetSummary() { return "Настраивает бота отдельно для этого сервера"; } -} +} \ No newline at end of file diff --git a/Boyfriend/EventHandler.cs b/Boyfriend/EventHandler.cs index 0435da4..bb484c8 100644 --- a/Boyfriend/EventHandler.cs +++ b/Boyfriend/EventHandler.cs @@ -36,12 +36,10 @@ public class EventHandler { Cacheable channel) { var msg = message.Value; - var toSend = msg == null - ? string.Format(Messages.UncachedMessageDeleted, Utils.MentionChannel(channel.Id)) + var toSend = msg == null ? string.Format(Messages.UncachedMessageDeleted, Utils.MentionChannel(channel.Id)) : string.Format(Messages.CachedMessageDeleted, msg.Author.Mention) + $"{Utils.MentionChannel(channel.Id)}: {Environment.NewLine}{Utils.Wrap(msg.Content)}"; - await Utils.SilentSendAsync(await Utils.GetAdminLogChannel( - Boyfriend.FindGuild(channel.Value)), toSend); + await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(Boyfriend.FindGuild(channel.Value)), toSend); } private static async Task MessageReceivedEvent(SocketMessage messageParam) { @@ -58,21 +56,20 @@ public class EventHandler { Messages.Culture = new CultureInfo(guildConfig.Lang!); - if ((message.MentionedUsers.Count > 3 || message.MentionedRoles.Count > 2) - && !user.GuildPermissions.MentionEveryone) + if ((message.MentionedUsers.Count > 3 || message.MentionedRoles.Count > 2) && + !user.GuildPermissions.MentionEveryone) await BanCommand.BanUser(guild, null, await guild.GetCurrentUserAsync(), user, TimeSpan.FromMilliseconds(-1), Messages.AutobanReason); try { prev = prevsArray[1].Content; prevFailsafe = prevsArray[2].Content; - } - catch (IndexOutOfRangeException) { } + } catch (IndexOutOfRangeException) {} - if (!(message.HasStringPrefix(guildConfig.Prefix, ref argPos) - || message.HasMentionPrefix(Boyfriend.Client.CurrentUser, ref argPos)) - || user == await guild.GetCurrentUserAsync() - || user.IsBot && (message.Content.Contains(prev) || message.Content.Contains(prevFailsafe))) + if (!(message.HasStringPrefix(guildConfig.Prefix, ref argPos) || + message.HasMentionPrefix(Boyfriend.Client.CurrentUser, ref argPos)) || + user == await guild.GetCurrentUserAsync() || + user.IsBot && (message.Content.Contains(prev) || message.Content.Contains(prevFailsafe))) return; await CommandHandler.HandleCommand(message); @@ -87,12 +84,10 @@ public class EventHandler { var toSend = msg == null ? string.Format(Messages.UncachedMessageEdited, messageSocket.Author.Mention, - Utils.MentionChannel(channel.Id)) + - Utils.Wrap(messageSocket.Content) - : string.Format(Messages.CachedMessageEdited, msg.Author.Mention, Utils.MentionChannel(channel.Id), nl, nl, + Utils.MentionChannel(channel.Id)) + Utils.Wrap(messageSocket.Content) : string.Format( + Messages.CachedMessageEdited, msg.Author.Mention, Utils.MentionChannel(channel.Id), nl, nl, Utils.Wrap(msg.Content), nl, nl, Utils.Wrap(messageSocket.Content)); - await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(Boyfriend.FindGuild(channel)), - toSend); + await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(Boyfriend.FindGuild(channel)), toSend); } private static async Task UserJoinedEvent(SocketGuildUser user) { @@ -100,10 +95,10 @@ public class EventHandler { var config = Boyfriend.GetGuildConfig(guild); if (config.SendWelcomeMessages.GetValueOrDefault(true)) - await Utils.SilentSendAsync(guild.SystemChannel, string.Format(config.WelcomeMessage!, user.Mention, - guild.Name)); + await Utils.SilentSendAsync(guild.SystemChannel, + string.Format(config.WelcomeMessage!, user.Mention, guild.Name)); if (config.DefaultRole != 0) await user.AddRoleAsync(Utils.ParseRole(guild, config.DefaultRole.ToString()!)); } -} +} \ No newline at end of file diff --git a/Boyfriend/GuildConfig.cs b/Boyfriend/GuildConfig.cs index 57654c4..59d25a3 100644 --- a/Boyfriend/GuildConfig.cs +++ b/Boyfriend/GuildConfig.cs @@ -1,9 +1,15 @@ using System.Globalization; using Newtonsoft.Json; +// ReSharper disable MemberCanBePrivate.Global namespace Boyfriend; public class GuildConfig { + + public GuildConfig(ulong id) { + Id = id; + Validate(); + } public ulong? Id { get; } public string? Lang { get; set; } public string? Prefix { get; set; } @@ -22,11 +28,6 @@ public class GuildConfig { public Dictionary>? RolesRemovedOnMute { get; private set; } - public GuildConfig(ulong id) { - Id = id; - Validate(); - } - public void Validate() { if (Id == null) throw new Exception("Something went horribly, horribly wrong"); diff --git a/Boyfriend/Messages.Designer.cs b/Boyfriend/Messages.Designer.cs index 1214e00..5f6d7f5 100644 --- a/Boyfriend/Messages.Designer.cs +++ b/Boyfriend/Messages.Designer.cs @@ -60,15 +60,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Arguments not present! {0}. - /// - internal static string ArgumentNotPresent { - get { - return ResourceManager.GetString("ArgumentNotPresent", resourceCulture); - } - } - /// /// Looks up a localized string similar to Too many mentions in 1 message. /// @@ -78,15 +69,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Invalid argument count! {0}. - /// - internal static string BadArgumentCount { - get { - return ResourceManager.GetString("BadArgumentCount", resourceCulture); - } - } - /// /// Looks up a localized string similar to :white_check_mark: Successfully banned {0} for {1}. /// @@ -141,6 +123,15 @@ namespace Boyfriend { } } + /// + /// Looks up a localized string similar to I cannot use time-outs on other bots! Try to set a mute role in settings. + /// + internal static string CannotTimeOutBot { + get { + return ResourceManager.GetString("CannotTimeOutBot", resourceCulture); + } + } + /// /// Looks up a localized string similar to Not specified. /// @@ -177,15 +168,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Command execution was unsuccessful: {0}. - /// - internal static string CommandExecutionUnsuccessful { - get { - return ResourceManager.GetString("CommandExecutionUnsuccessful", resourceCulture); - } - } - /// /// Looks up a localized string similar to Command help:{0}. /// @@ -213,15 +195,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Command parsing failed: {0}. - /// - internal static string CommandParseFailed { - get { - return ResourceManager.GetString("CommandParseFailed", resourceCulture); - } - } - /// /// Looks up a localized string similar to Couldn't find guild by message!. /// @@ -348,6 +321,24 @@ 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 forever using timeouts! Either specify a proper duration, or set a mute role in settings. + /// + internal static string DurationRequiredForTimeOuts { + get { + return ResourceManager.GetString("DurationRequiredForTimeOuts", resourceCulture); + } + } + /// /// Looks up a localized string similar to Members are in different guilds!. /// @@ -403,38 +394,29 @@ namespace Boyfriend { } /// - /// Looks up a localized string similar to Invalid admin log channel for guild. + /// Looks up a localized string similar to This channel does not exist!. /// - internal static string InvalidAdminLogChannel { + internal static string InvalidChannel { get { - return ResourceManager.GetString("InvalidAdminLogChannel", resourceCulture); + return ResourceManager.GetString("InvalidChannel", resourceCulture); } } /// - /// Looks up a localized string similar to Invalid argument! 'true' or 'false' required!. + /// Looks up a localized string similar to This role does not exist!. /// - internal static string InvalidBoolean { + internal static string InvalidRole { get { - return ResourceManager.GetString("InvalidBoolean", resourceCulture); + return ResourceManager.GetString("InvalidRole", resourceCulture); } } /// - /// Looks up a localized string similar to Invalid channel specified!. + /// Looks up a localized string similar to Invalid setting value specified!. /// - internal static string InvalidChannelSpecified { + internal static string InvalidSettingValue { get { - return ResourceManager.GetString("InvalidChannelSpecified", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid role specified!. - /// - internal static string InvalidRoleSpecified { - get { - return ResourceManager.GetString("InvalidRoleSpecified", resourceCulture); + return ResourceManager.GetString("InvalidSettingValue", resourceCulture); } } @@ -528,24 +510,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Someone removed the mute role manually!. - /// - internal static string MuteRoleManuallyRemoved { - get { - return ResourceManager.GetString("MuteRoleManuallyRemoved", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You must set up a mute role in settings!. - /// - internal static string MuteRoleRequired { - get { - return ResourceManager.GetString("MuteRoleRequired", resourceCulture); - } - } - /// /// Looks up a localized string similar to No. /// @@ -591,15 +555,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Repeated arguments detected! {0}. - /// - internal static string RepeatedArgumentsDetected { - get { - return ResourceManager.GetString("RepeatedArgumentsDetected", resourceCulture); - } - } - /// /// Looks up a localized string similar to Not specified. /// @@ -609,6 +564,15 @@ namespace Boyfriend { } } + /// + /// Looks up a localized string similar to I couldn't remove role {0} because of an error! {1}. + /// + internal static string RoleRemovalFailed { + get { + return ResourceManager.GetString("RoleRemovalFailed", resourceCulture); + } + } + /// /// Looks up a localized string similar to Someone removed the mute role manually! I added back all roles that I removed during the mute. /// @@ -655,7 +619,7 @@ namespace Boyfriend { } /// - /// Looks up a localized string similar to Message edited from {0} in channel {1}, but I forgot what was there before the edit. + /// Looks up a localized string similar to Message edited from {0} in channel {1}, but I forgot what was there before the edit: . /// internal static string UncachedMessageEdited { get { @@ -663,15 +627,6 @@ namespace Boyfriend { } } - /// - /// Looks up a localized string similar to Unknown command! {0}. - /// - internal static string UnknownCommand { - get { - return ResourceManager.GetString("UnknownCommand", resourceCulture); - } - } - /// /// Looks up a localized string similar to :white_check_mark: Successfully unmuted {0} for {1}. /// diff --git a/Boyfriend/Messages.resx b/Boyfriend/Messages.resx index 1714f55..6f8ac2e 100644 --- a/Boyfriend/Messages.resx +++ b/Boyfriend/Messages.resx @@ -40,7 +40,7 @@ Too many mentions in 1 message - Message edited from {0} in channel {1}, but I forgot what was there before the edit + Message edited from {0} in channel {1}, but I forgot what was there before the edit: Message edited from {0} in channel {1}.{2}Before:{3}{4}{5}After:{6}{7} @@ -57,30 +57,6 @@ Beep! - - Invalid admin log channel for guild - - - You must set up a mute role in settings! - - - Command execution was unsuccessful: {0} - - - Repeated arguments detected! {0} - - - Command parsing failed: {0} - - - Unknown command! {0} - - - Invalid argument count! {0} - - - Arguments not present! {0} - I do not have permission to execute this command! @@ -141,9 +117,6 @@ Member is already muted! - - Someone removed the mute role manually! - Not specified @@ -186,15 +159,6 @@ Settings successfully updated - - Invalid argument! 'true' or 'false' required! - - - Invalid role specified! - - - Invalid channel specified! - Yes @@ -252,4 +216,25 @@ {0}This punishment will expire <t:{1}:R> + + Invalid setting value specified! + + + This role does not exist! + + + 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} + + + I cannot mute someone forever using timeouts! Either specify a proper duration, or set a mute role in settings + + + I cannot use time-outs on other bots! Try to set a mute role in settings + \ No newline at end of file diff --git a/Boyfriend/Messages.ru.resx b/Boyfriend/Messages.ru.resx index 7ff5cd2..0aad39e 100644 --- a/Boyfriend/Messages.ru.resx +++ b/Boyfriend/Messages.ru.resx @@ -31,7 +31,7 @@ Слишком много упоминаний в одном сообщении - Отредактировано сообщение от {0} в канале {1}, но я забыл что там было до редактирования + Отредактировано сообщение от {0} в канале {1}, но я забыл что там было до редактирования: Отредактировано сообщение от {0} в канале {1}.{2}До:{3}{4}{5}После:{6}{7} @@ -48,30 +48,6 @@ Бип! - - Требуется указать роль мута в настройках! - - - Неверный канал админ-логов для гильдии - - - Выполнение команды завершилось неудачей: {0} - - - Обнаружены повторяющиеся типы аргументов! {0} - - - Не удалось обработать команду: {0} - - - Неизвестная команда! {0} - - - Неверное количество аргументов! {0} - - - Нету нужных аргументов! {0} - У меня недостаточно прав для выполнения этой команды! @@ -132,9 +108,6 @@ Участник уже заглушен! - - Кто-то убрал роль мута самостоятельно! - Не указан @@ -177,15 +150,6 @@ Настройки успешно обновлены! - - Неверный параметр! Требуется 'true' или 'false' - - - Указана недействительная роль! - - - Указан недействильный канал! - Да @@ -243,4 +207,25 @@ {0}Это наказание истечёт <t:{1}:R> + + Указано недействительное значение для настройки! + + + Эта роль не существует! + + + Этот канал не существует! + + + Мне не удалось обработать продолжительность! Один из компонентов может быть за пределами допустимого диапазона (например, `24ч` или `60м`) + + + Я не смог забрать роль {0} в связи с ошибкой! {1} + + + Я не могу заглушить кого-то навсегда, используя тайм-ауты! Или укажи правильную продолжительность, или установи роль мута в настройках + + + Я не могу использовать тайм-ауты на других ботах! Попробуй указать роль мута в настройках + \ No newline at end of file diff --git a/Boyfriend/Utils.cs b/Boyfriend/Utils.cs index bfc3756..8795c82 100644 --- a/Boyfriend/Utils.cs +++ b/Boyfriend/Utils.cs @@ -27,12 +27,12 @@ public static class Utils { } public static string Wrap(string original) { - var toReturn = original.Replace("```", "​`​`​`​"); + var toReturn = original.Replace("```", "ˋˋˋ"); return $"```{toReturn}{(toReturn.EndsWith("`") || toReturn.Trim().Equals("") ? " " : "")}```"; } public static string WrapInline(string original) { - return $"`{original}`"; + return $"`{original.Replace("`", "ˋ")}`"; } public static string MentionChannel(ulong id) { @@ -64,7 +64,7 @@ public static class Utils { return await Boyfriend.Client.GetChannelAsync(ParseMention(mention)); } - public static async Task ParseChannelNullable(string mention) { + private static async Task ParseChannelNullable(string mention) { return ParseMentionNullable(mention) == null ? null : await ParseChannel(mention); } @@ -72,10 +72,6 @@ public static class Utils { return guild.GetRole(ParseMention(mention)); } - public static IRole? ParseRoleNullable(IGuild guild, string mention) { - return ParseMentionNullable(mention) == null ? null : ParseRole(guild, mention); - } - public static async Task SendDirectMessage(IUser user, string toSend) { try { await user.SendMessageAsync(toSend); @@ -98,8 +94,7 @@ public static class Utils { } catch (ArgumentException) {} } public static TimeSpan GetTimeSpan(string from) { - return TimeSpan.ParseExact(from.ToLowerInvariant(), Formats, - CultureInfo.InvariantCulture); + return TimeSpan.ParseExact(from.ToLowerInvariant(), Formats, CultureInfo.InvariantCulture); } public static string JoinString(string[] args, int startIndex) { @@ -115,4 +110,4 @@ public static class Utils { options.AuditLogReason = reason; return options; } -} +} \ No newline at end of file