diff --git a/.gitignore b/.gitignore index f6f24756..4a27b2f1 100644 --- a/.gitignore +++ b/.gitignore @@ -357,5 +357,4 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ -# End of https://www.toptal.com/developers/gitignore/api/visualstudio -src/FlawBOT/Lavalink.jar +# End of https://www.toptal.com/developers/gitignore/api/visualstudio \ No newline at end of file diff --git a/README.md b/README.md index 26efa32a..d2b4557e 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ A Discord bot written in C# using the [DSharpPlus](https://github.com/DSharpPlus ## Installation To run your own instance of FlawBOT, [clone this repository](https://github.com/CriticalFlaw/FlawBOT/archive/master.zip) or [download the release package](https://github.com/CriticalFlaw/FlawBOT/releases) and modify the provided **config.json** file, adding the API tokens. If you're cloning the repository, use [Visual Studio 2019](https://www.visualstudio.com/downloads/) to compile the project. +## Running FlawBOT +As of version 3.0, FlawBOT requires a [Lavalink](https://github.com/Frederikam/Lavalink#requirements) node to be running in order to play music and not display lavalink-related errors in console. `lavalink.jar` and `application.yml` are included in the project directory, so all you have to do is open the command prompt and launch lavalink with the command `java -jar Lavalink.jar` (be sure to install [Java 13 or later](https://www.oracle.com/java/technologies/javase-jdk13-downloads.html)). + ## API Tokens * [Discord](https://discordapp.com/developers/applications/me) (*required*) * [Steam](https://steamcommunity.com/dev/apikey) diff --git a/src/FlawBOT/Common/Exceptions.cs b/src/FlawBOT/Common/Exceptions.cs index 9ad145b1..429f5b95 100644 --- a/src/FlawBOT/Common/Exceptions.cs +++ b/src/FlawBOT/Common/Exceptions.cs @@ -17,78 +17,78 @@ public static async Task Process(CommandErrorEventArgs e, EventId eventId) { switch (e.Exception) { - case CommandNotFoundException _: - await BotServices.SendEmbedAsync(e.Context, e.Exception.Message, EmbedType.Missing) + case CommandNotFoundException: + await BotServices.SendResponseAsync(e.Context, e.Exception.Message, ResponseType.Missing) .ConfigureAwait(false); break; - case InvalidOperationException _: - await BotServices.SendEmbedAsync(e.Context, e.Exception.Message, EmbedType.Warning) + case InvalidOperationException: + await BotServices.SendResponseAsync(e.Context, e.Exception.Message, ResponseType.Warning) .ConfigureAwait(false); break; case ChecksFailedException cfe: - await BotServices.SendEmbedAsync(e.Context, - $"Command **{e.Command.QualifiedName}** could not be executed.", EmbedType.Error) + await BotServices.SendResponseAsync(e.Context, + $"Command {Formatter.Bold(e.Command.QualifiedName)} could not be executed.", ResponseType.Error) .ConfigureAwait(false); foreach (var check in cfe.FailedChecks) switch (check) { case RequirePermissionsAttribute perms: - await BotServices.SendEmbedAsync(e.Context, + await BotServices.SendResponseAsync(e.Context, $"- One of us does not have the required permissions ({perms.Permissions.ToPermissionString()})!", - EmbedType.Error).ConfigureAwait(false); + ResponseType.Error).ConfigureAwait(false); break; case RequireUserPermissionsAttribute perms: - await BotServices.SendEmbedAsync(e.Context, + await BotServices.SendResponseAsync(e.Context, $"- You do not have sufficient permissions ({perms.Permissions.ToPermissionString()})!", - EmbedType.Error).ConfigureAwait(false); + ResponseType.Error).ConfigureAwait(false); break; case RequireBotPermissionsAttribute perms: - await BotServices.SendEmbedAsync(e.Context, + await BotServices.SendResponseAsync(e.Context, $"- I do not have sufficient permissions ({perms.Permissions.ToPermissionString()})!", - EmbedType.Error).ConfigureAwait(false); + ResponseType.Error).ConfigureAwait(false); break; - case RequireOwnerAttribute _: - await BotServices.SendEmbedAsync(e.Context, - "- This command is reserved only for the bot owner.", EmbedType.Error) + case RequireOwnerAttribute: + await BotServices.SendResponseAsync(e.Context, + "- This command is reserved only for the bot owner.", ResponseType.Error) .ConfigureAwait(false); break; case RequirePrefixesAttribute pa: - await BotServices.SendEmbedAsync(e.Context, + await BotServices.SendResponseAsync(e.Context, $"- This command can only be invoked with the following prefixes: {string.Join(" ", pa.Prefixes)}.", - EmbedType.Error).ConfigureAwait(false); + ResponseType.Error).ConfigureAwait(false); break; default: - await BotServices.SendEmbedAsync(e.Context, + await BotServices.SendResponseAsync(e.Context, "Unknown check triggered. Please notify the developer using the command *.bot report*", - EmbedType.Error).ConfigureAwait(false); + ResponseType.Error).ConfigureAwait(false); break; } break; - case ArgumentNullException _: - case ArgumentException _: - await BotServices.SendEmbedAsync(e.Context, + case ArgumentNullException: + case ArgumentException: + await BotServices.SendResponseAsync(e.Context, $"Invalid or missing parameters. For help, use command `.help {e.Command?.QualifiedName}`", - EmbedType.Warning); + ResponseType.Warning); break; - case UnauthorizedException _: - await BotServices.SendEmbedAsync(e.Context, "One of us does not have the required permissions.", EmbedType.Warning); + case UnauthorizedException: + await BotServices.SendResponseAsync(e.Context, "One of us does not have the required permissions.", ResponseType.Warning); break; - case NullReferenceException _: - case InvalidDataException _: + case NullReferenceException: + case InvalidDataException: e.Context.Client.Logger.LogWarning(eventId, e.Exception, $"[{e.Context.Guild.Name} : {e.Context.Channel.Name}] {e.Context.User.Username} executed the command '{e.Command?.QualifiedName ?? ""}' but it threw an error: "); - await BotServices.SendEmbedAsync(e.Context, e.Exception.Message, EmbedType.Error); + await BotServices.SendResponseAsync(e.Context, e.Exception.Message, ResponseType.Error); break; default: diff --git a/src/FlawBOT/Common/HelpFormatter.cs b/src/FlawBOT/Common/HelpFormatter.cs index 08be1d63..385315f8 100644 --- a/src/FlawBOT/Common/HelpFormatter.cs +++ b/src/FlawBOT/Common/HelpFormatter.cs @@ -41,33 +41,36 @@ public override BaseHelpFormatter WithCommand(Command cmd) _name = (cmd is CommandGroup ? "Group: " : "Command: ") + cmd.QualifiedName; _description = cmd.Description; - if (cmd.Overloads?.Any() ?? false) - foreach (var overload in cmd.Overloads.OrderByDescending(o => o.Priority)) + if (cmd.Aliases?.Any() ?? false) + _output.AddField("Aliases", string.Join(", ", cmd.Aliases.Select(Formatter.InlineCode)), true); + + if (!(cmd.Overloads?.Any() ?? false)) return this; + foreach (var overload in cmd.Overloads.OrderByDescending(o => o.Priority)) + { + if (overload.Arguments.Count == 0) continue; + + var args = new StringBuilder(); + foreach (var arg in overload.Arguments) { - var args = new StringBuilder(); - foreach (var arg in overload.Arguments) + args.Append(Formatter.InlineCode($"[{CommandsNext.GetUserFriendlyTypeName(arg.Type)}]")); + args.Append(' '); + args.Append(arg.Description ?? "No description provided."); + if (arg.IsOptional) { - args.Append(Formatter.InlineCode($"[{CommandsNext.GetUserFriendlyTypeName(arg.Type)}]")); - args.Append(' '); - args.Append(arg.Description ?? "No description provided."); - if (arg.IsOptional) - { - args.Append(" (def: ") - .Append(Formatter.InlineCode(arg.DefaultValue is null - ? "None" - : arg.DefaultValue.ToString())).Append(')'); - args.Append(" (optional)"); - } - - args.AppendLine(); + args.Append(" (def: ") + .Append(Formatter.InlineCode(arg.DefaultValue is null + ? "None" + : arg.DefaultValue.ToString())).Append(')'); + args.Append(" (optional)"); } - _output.AddField($"{(cmd.Overloads.Count > 1 ? $"Overload #{overload.Priority}" : "Arguments")}", - args.ToString() ?? "No arguments."); + args.AppendLine(); } - if (cmd.Aliases?.Any() ?? false) - _output.AddField("Aliases", string.Join(", ", cmd.Aliases.Select(Formatter.InlineCode)), true); + _output.AddField($"{(cmd.Overloads.Count > 1 ? $"Overload #{overload.Priority}" : "Arguments")}", + args.ToString() ?? "No arguments."); + } + return this; } diff --git a/src/FlawBOT/Common/SharedData.cs b/src/FlawBOT/Common/SharedData.cs index deec2efc..7f0118fa 100644 --- a/src/FlawBOT/Common/SharedData.cs +++ b/src/FlawBOT/Common/SharedData.cs @@ -18,7 +18,7 @@ public static class SharedData public static int ShardCount { get; } = 1; } - public enum EmbedType + public enum ResponseType { Default, Warning, diff --git a/src/FlawBOT/FlawBOT.cs b/src/FlawBOT/FlawBOT.cs index 7ebab6f0..2aac5478 100644 --- a/src/FlawBOT/FlawBOT.cs +++ b/src/FlawBOT/FlawBOT.cs @@ -61,7 +61,6 @@ public FlawBot(int shardId = 0) EnableMentionPrefix = true, // Set the boolean for mentioning the bot as a command prefix CaseSensitive = false, IgnoreExtraArguments = true, - EnableDefaultHelp = false, Services = Services }); Commands.CommandExecuted += Command_Executed; @@ -72,11 +71,12 @@ public FlawBot(int shardId = 0) Commands.RegisterCommands(); Commands.RegisterCommands(); Commands.RegisterCommands(); - Commands.RegisterCommands(); Commands.RegisterCommands(); Commands.RegisterCommands(); Commands.RegisterCommands(); + Commands.RegisterCommands(); Commands.RegisterCommands(); + Commands.RegisterCommands(); Commands.RegisterCommands(); Commands.RegisterCommands(); Commands.RegisterCommands(); @@ -90,8 +90,8 @@ public FlawBot(int shardId = 0) Commands.RegisterCommands(); Commands.RegisterCommands(); Commands.RegisterCommands(); + Commands.RegisterCommands(); Commands.RegisterCommands(); - Commands.RegisterCommands(); // Setup Interactivity Interactivity = Client.UseInteractivity(new InteractivityConfiguration @@ -109,9 +109,10 @@ public FlawBot(int shardId = 0) // Setup Lavalink Lavalink = Client.UseLavalink(); + //Process.Start("java", $"-jar {Directory.GetCurrentDirectory()}\\Lavalink.jar"); // Start the uptime counter - Console.Title = SharedData.Name + "-" + SharedData.Version; + Console.Title = $"{SharedData.Name}-{SharedData.Version}"; SharedData.ProcessStarted = DateTime.Now; } @@ -127,9 +128,9 @@ public async Task RunAsync() { // Update any other services that are being used. Client.Logger.LogInformation(EventId, "Loading..."); - //await SteamService.UpdateSteamAppListAsync().ConfigureAwait(false); - //await TeamFortressService.UpdateTf2SchemaAsync().ConfigureAwait(false); - //await PokemonService.UpdatePokemonListAsync().ConfigureAwait(false); + await SteamService.UpdateSteamAppListAsync().ConfigureAwait(false); + await TeamFortressService.UpdateTf2SchemaAsync().ConfigureAwait(false); + await PokemonService.UpdatePokemonListAsync().ConfigureAwait(false); // Set the initial activity and connect the bot to Discord var act = new DiscordActivity("Night of Fire", ActivityType.ListeningTo); @@ -184,7 +185,7 @@ private async Task Client_VoiceStateUpdated(DiscordClient sender, VoiceStateUpda if (channel == null || channel != e.Before.Channel) return; var users = channel.Users; - if (musicData.IsPlaying && !users.Any(x => !x.IsBot)) + if (musicData.IsPlaying && users.All(x => x.IsBot)) { sender.Logger.LogInformation(EventId, $"All users left voice in {e.Guild.Name}, pausing playback..."); await musicData.PauseAsync(); diff --git a/src/FlawBOT/FlawBOT.csproj b/src/FlawBOT/FlawBOT.csproj index 87ba1fca..d935d466 100644 --- a/src/FlawBOT/FlawBOT.csproj +++ b/src/FlawBOT/FlawBOT.csproj @@ -25,12 +25,13 @@ false - AnyCPU + x86 + @@ -40,6 +41,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/FlawBOT/Lavalink.jar b/src/FlawBOT/Lavalink.jar new file mode 100644 index 00000000..74922a7d Binary files /dev/null and b/src/FlawBOT/Lavalink.jar differ diff --git a/src/FlawBOT/Models/WorldData.cs b/src/FlawBOT/Models/WorldData.cs index c386dec8..209c599c 100644 --- a/src/FlawBOT/Models/WorldData.cs +++ b/src/FlawBOT/Models/WorldData.cs @@ -97,10 +97,10 @@ public class Location public string LocalTime { get; set; } [JsonProperty("localtime_epoch", NullValueHandling = NullValueHandling.Ignore)] - public int LocalTime_epoch { get; set; } + public int LocalTimeEpoch { get; set; } [JsonProperty("utc_offset", NullValueHandling = NullValueHandling.Ignore)] - public string UTC_Offset { get; set; } + public string UtcOffset { get; set; } } public class Current @@ -121,13 +121,13 @@ public class Current public List Descriptions { get; set; } [JsonProperty("wind_speed", NullValueHandling = NullValueHandling.Ignore)] - public int Wind_Speed { get; set; } + public int WindSpeed { get; set; } [JsonProperty("wind_degree", NullValueHandling = NullValueHandling.Ignore)] - public int Wind_Degree { get; set; } + public int WindDegree { get; set; } [JsonProperty("wind_dir", NullValueHandling = NullValueHandling.Ignore)] - public string Wind_Direction { get; set; } + public string WindDirection { get; set; } [JsonProperty("pressure", NullValueHandling = NullValueHandling.Ignore)] public int Pressure { get; set; } @@ -145,7 +145,7 @@ public class Current public int FeelsLike { get; set; } [JsonProperty("uv_index", NullValueHandling = NullValueHandling.Ignore)] - public int UV_Index { get; set; } + public int UvIndex { get; set; } [JsonProperty("visibility", NullValueHandling = NullValueHandling.Ignore)] public int Visibility { get; set; } diff --git a/src/FlawBOT/Modules/Bot/BotModule.cs b/src/FlawBOT/Modules/Bot/BotModule.cs index 46751101..07ccae03 100644 --- a/src/FlawBOT/Modules/Bot/BotModule.cs +++ b/src/FlawBOT/Modules/Bot/BotModule.cs @@ -10,14 +10,14 @@ namespace FlawBOT.Modules { - [Group("bot")] + [Group("bot"),] [Description("Basic commands for interacting with FlawBOT")] [Cooldown(3, 5, CooldownBucketType.Channel)] public class BotModule : BaseCommandModule { #region COMMAND_INFO - [Command("info"), Aliases("i", "about")] + [Command("info"), Aliases("about")] [Description("Retrieve FlawBOT information")] public async Task BotInfo(CommandContext ctx) { @@ -30,7 +30,7 @@ public async Task BotInfo(CommandContext ctx) $"{(int)uptime.TotalDays:00} days {uptime.Hours:00}:{uptime.Minutes:00}:{uptime.Seconds:00}", true) .AddField(":link: Links", $"[Commands]({SharedData.GitHubLink}wiki) **|** [GitHub]({SharedData.GitHubLink})", true) - .WithFooter("Thank you for using " + SharedData.Name + $" (v{SharedData.Version})") + .WithFooter($"Thank you for using {SharedData.Name} (v{SharedData.Version})") .WithUrl(SharedData.GitHubLink) .WithColor(SharedData.DefaultColor); await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false); @@ -45,7 +45,7 @@ public async Task BotInfo(CommandContext ctx) [RequireUserPermissions(Permissions.Administrator)] public async Task LeaveServer(CommandContext ctx) { - await ctx.RespondAsync($"Are you sure you want {SharedData.Name} to leave this server?") + await ctx.RespondAsync($"Are you sure you want {SharedData.Name} to leave the server?") .ConfigureAwait(false); var message = await ctx .RespondAsync(Resources.INFO_RESPOND) @@ -53,12 +53,12 @@ await ctx.RespondAsync($"Are you sure you want {SharedData.Name} to leave this s var interactivity = await BotServices.GetUserInteractivity(ctx, "yes", 10).ConfigureAwait(false); if (interactivity.Result is null) { - await message.ModifyAsync("~~" + message.Content + "~~ " + Resources.INFO_REQ_TIMEOUT) + await message.ModifyAsync($"~~{message.Content}~~ {Resources.INFO_REQ_TIMEOUT}") .ConfigureAwait(false); return; } - await BotServices.SendEmbedAsync(ctx, "Thank you for using " + SharedData.Name).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, $"Thank you for using {SharedData.Name}").ConfigureAwait(false); await ctx.Guild.LeaveAsync().ConfigureAwait(false); } @@ -68,9 +68,9 @@ await message.ModifyAsync("~~" + message.Content + "~~ " + Resources.INFO_REQ_TI [Command("ping"), Aliases("pong")] [Description("Ping the FlawBOT client")] - public async Task Ping(CommandContext ctx) + public async Task PingBot(CommandContext ctx) { - await BotServices.SendEmbedAsync(ctx, $":ping_pong: Pong! Ping: **{ctx.Client.Ping}**ms") + await BotServices.SendResponseAsync(ctx, $":ping_pong: Pong! Ping: **{ctx.Client.Ping}**ms") .ConfigureAwait(false); } @@ -90,16 +90,14 @@ public async Task ReportIssue(CommandContext ctx, return; } - await ctx.RespondAsync( - "The following information will be sent to the developer for investigation: User ID, Server ID, Server Name and Server Owner Name.") - .ConfigureAwait(false); + await ctx.RespondAsync(Resources.INFO_REPORT_SENDER).ConfigureAwait(false); var message = await ctx .RespondAsync(Resources.INFO_RESPOND) .ConfigureAwait(false); var interactivity = await BotServices.GetUserInteractivity(ctx, "yes", 10).ConfigureAwait(false); if (interactivity.Result is null) { - await message.ModifyAsync("~~" + message.Content + "~~ " + Resources.INFO_REQ_TIMEOUT) + await message.ModifyAsync($"~~{message.Content}~~ {Resources.INFO_REQ_TIMEOUT}") .ConfigureAwait(false); } else @@ -122,37 +120,6 @@ await message.ModifyAsync("~~" + message.Content + "~~ " + Resources.INFO_REQ_TI #endregion COMMAND_REPORT - #region COMMAND_SAY - - [Hidden, Command("say"), Aliases("echo")] - [Description("Make FlawBOT repeat a message")] - public async Task Say(CommandContext ctx, - [Description("Message for the bot to repeat"), RemainingText] - string message) - { - await BotServices.RemoveMessage(ctx.Message).ConfigureAwait(false); - await ctx.RespondAsync(message ?? ":thinking:").ConfigureAwait(false); - } - - #endregion COMMAND_SAY - - #region COMMAND_TTS - - [Command("tts"), Aliases("talk")] - [Description("Make FlawBOT repeat a message in text-to-speech")] - [RequirePermissions(Permissions.SendTtsMessages)] - public async Task SayTts(CommandContext ctx, - [Description("Message for the bot to convert to speech"), RemainingText] - string message) - { - if (string.IsNullOrWhiteSpace(message)) - await ctx.RespondAsync(":thinking:").ConfigureAwait(false); - else - await ctx.RespondAsync(Formatter.BlockCode(Formatter.Strip(message)), true).ConfigureAwait(false); - } - - #endregion COMMAND_TTS - #region COMMAND_UPTIME [Command("uptime"), Aliases("time")] @@ -161,7 +128,7 @@ public async Task Uptime(CommandContext ctx) { var uptime = DateTime.Now - SharedData.ProcessStarted; var days = uptime.Days > 0 ? $"({uptime.Days:00} days)" : string.Empty; - await BotServices.SendEmbedAsync(ctx, + await BotServices.SendResponseAsync(ctx, $":clock1: {SharedData.Name} has been online for {uptime.Hours:00}:{uptime.Minutes:00}:{uptime.Seconds} {days}") .ConfigureAwait(false); } @@ -221,19 +188,19 @@ public async Task SetBotStatus(CommandContext ctx, case "OFF": case "OFFLINE": await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Offline).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, $"{SharedData.Name} status has been changed to Offline") + await BotServices.SendResponseAsync(ctx, $"{SharedData.Name} status has been changed to Offline") .ConfigureAwait(false); break; case "INVISIBLE": await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Invisible).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, $"{SharedData.Name} status has been changed to Invisible") + await BotServices.SendResponseAsync(ctx, $"{SharedData.Name} status has been changed to Invisible") .ConfigureAwait(false); break; case "IDLE": await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Idle).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, $"{SharedData.Name} status has been changed to Idle") + await BotServices.SendResponseAsync(ctx, $"{SharedData.Name} status has been changed to Idle") .ConfigureAwait(false); break; @@ -241,13 +208,13 @@ await BotServices.SendEmbedAsync(ctx, $"{SharedData.Name} status has been change case "DO NOT DISTURB": await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.DoNotDisturb).ConfigureAwait(false); await BotServices - .SendEmbedAsync(ctx, $"{SharedData.Name} status has been changed to Do Not Disturb") + .SendResponseAsync(ctx, $"{SharedData.Name} status has been changed to Do Not Disturb") .ConfigureAwait(false); break; default: await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Online).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, $"{SharedData.Name} status has been changed to Online") + await BotServices.SendResponseAsync(ctx, $"{SharedData.Name} status has been changed to Online") .ConfigureAwait(false); break; } @@ -266,7 +233,7 @@ public async Task SetBotUsername(CommandContext ctx, var oldName = ctx.Client.CurrentUser.Username; var newName = string.IsNullOrWhiteSpace(name) ? SharedData.Name : name; await ctx.Client.UpdateCurrentUserAsync(newName).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, $"{oldName}'s username has been changed to {newName}") + await BotServices.SendResponseAsync(ctx, $"{oldName}'s username has been changed to {newName}") .ConfigureAwait(false); } diff --git a/src/FlawBOT/Modules/Bot/MusicModule.cs b/src/FlawBOT/Modules/Bot/MusicModule.cs index 8496cb8a..a2c24825 100644 --- a/src/FlawBOT/Modules/Bot/MusicModule.cs +++ b/src/FlawBOT/Modules/Bot/MusicModule.cs @@ -162,7 +162,7 @@ public async Task PlaySong(CommandContext ctx, [RemainingText] string query) var results = await YouTube.GetMusicDataAsync(query); if (!results.Any()) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Games/PokemonModule.cs b/src/FlawBOT/Modules/Games/PokemonModule.cs index 04395637..d326f086 100644 --- a/src/FlawBOT/Modules/Games/PokemonModule.cs +++ b/src/FlawBOT/Modules/Games/PokemonModule.cs @@ -19,12 +19,12 @@ public class PokemonModule : BaseCommandModule [Description("Retrieve a Pokémon card")] public async Task Pokemon(CommandContext ctx, [Description("Name of the Pokémon"), RemainingText] - string query) + string query = "") { var results = await PokemonService.GetPokemonCardsAsync(query).ConfigureAwait(false); if (results.Cards.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Games/SpeedrunModule.cs b/src/FlawBOT/Modules/Games/SpeedrunModule.cs index 93a4b65c..c03212cf 100644 --- a/src/FlawBOT/Modules/Games/SpeedrunModule.cs +++ b/src/FlawBOT/Modules/Games/SpeedrunModule.cs @@ -26,7 +26,7 @@ public async Task Speedrun(CommandContext ctx, var results = SpeedrunService.GetSpeedrunGameAsync(query).Result; if (results is null || results.Data.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -41,7 +41,7 @@ await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Miss .AddField("Publishers", SpeedrunService.GetSpeedrunExtraAsync(game.Publishers, SpeedrunExtras.Publishers).Result ?? "Unknown", true) - .AddField("Release Date", game.ReleaseDate ?? "Unknown", true) + .AddField("Release Date", game.ReleaseDate ?? "Unknown") .AddField("Platforms", SpeedrunService.GetSpeedrunExtraAsync(game.Platforms, SpeedrunExtras.Platforms).Result ?? "Unknown") diff --git a/src/FlawBOT/Modules/Games/SteamModule.cs b/src/FlawBOT/Modules/Games/SteamModule.cs index fd36c846..5cdc74d9 100644 --- a/src/FlawBOT/Modules/Games/SteamModule.cs +++ b/src/FlawBOT/Modules/Games/SteamModule.cs @@ -32,7 +32,7 @@ public async Task SteamGame(CommandContext ctx, var app = SteamService.GetSteamAppAsync(query).Result; if (app is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -81,12 +81,12 @@ public async Task SteamUser(CommandContext ctx, var profile = SteamService.GetSteamProfileAsync(query).Result; if (profile is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); } else if (profile.Data.ProfileVisibility == ProfileVisibility.Private) { - await BotServices.SendEmbedAsync(ctx, "This profile is private...", EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, "This profile is private...", ResponseType.Warning) .ConfigureAwait(false); } else @@ -131,7 +131,7 @@ await ctx.RespondAsync( string.Format($"steam://connect/{regex.Groups["ip"].Value}/{regex.Groups["pw"].Value}")) .ConfigureAwait(false); else - await BotServices.SendEmbedAsync(ctx, Resources.ERR_INVALID_IP_GAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_INVALID_IP_GAME, ResponseType.Warning) .ConfigureAwait(false); } diff --git a/src/FlawBOT/Modules/Games/TeamFortressModule.cs b/src/FlawBOT/Modules/Games/TeamFortressModule.cs index 246a1d4d..4d612296 100644 --- a/src/FlawBOT/Modules/Games/TeamFortressModule.cs +++ b/src/FlawBOT/Modules/Games/TeamFortressModule.cs @@ -30,7 +30,7 @@ public async Task Tf2Schema(CommandContext ctx, var item = TeamFortressService.GetSchemaItem(query); if (item is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -77,7 +77,7 @@ public async Task Tf2Map(CommandContext ctx, var results = await TeamFortressService.GetMapStatsAsync(query.ToLowerInvariant()).ConfigureAwait(false); if (results is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -137,7 +137,7 @@ public async Task Tf2News(CommandContext ctx, var results = await TeamFortressService.GetNewsArticlesAsync(query).ConfigureAwait(false); if (results is null || results.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -180,7 +180,7 @@ public async Task Tf2Creators(CommandContext ctx, var steamId = SteamService.GetSteamUserId(query).Result; if (steamId is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -188,7 +188,7 @@ await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Miss var results = await TeamFortressService.GetContentCreatorAsync(steamId.Data).ConfigureAwait(false); if (results.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -246,7 +246,7 @@ public async Task Tf2ServerByMode(CommandContext ctx, .ConfigureAwait(false); if (results is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -291,7 +291,7 @@ public async Task Tf2ServerByIp(CommandContext ctx, { if (string.IsNullOrWhiteSpace(ip) || !IPAddress.TryParse(ip, out var address)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_INVALID_IP, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.ERR_INVALID_IP, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Misc/MathModule.cs b/src/FlawBOT/Modules/Misc/MathModule.cs index b81ef0bf..47132b8f 100644 --- a/src/FlawBOT/Modules/Misc/MathModule.cs +++ b/src/FlawBOT/Modules/Misc/MathModule.cs @@ -32,13 +32,13 @@ public async Task Math(CommandContext ctx, _ => num1 + num2 }; var output = new DiscordEmbedBuilder() - .WithDescription($":1234: The result is {result:#,##0.00}") + .WithDescription($":1234: The answer is {result:#,##0.00}") .WithColor(DiscordColor.CornflowerBlue); await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false); } catch { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_MATH_EQUATION, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_MATH_EQUATION, ResponseType.Warning) .ConfigureAwait(false); } } diff --git a/src/FlawBOT/Modules/Misc/MiscModule.cs b/src/FlawBOT/Modules/Misc/MiscModule.cs index e1870a1c..47792b48 100644 --- a/src/FlawBOT/Modules/Misc/MiscModule.cs +++ b/src/FlawBOT/Modules/Misc/MiscModule.cs @@ -92,7 +92,7 @@ public async Task GetDog(CommandContext ctx) var results = MiscService.GetDogPhotoAsync().Result; if (results.Status != "success") { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_API_CONNECTION, EmbedType.Warning).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, Resources.ERR_API_CONNECTION, ResponseType.Warning).ConfigureAwait(false); return; } @@ -113,12 +113,27 @@ public async Task Greet(CommandContext ctx, DiscordMember member) { if (member is null) - await ctx.RespondAsync(":wave: Hello, " + ctx.User.Mention).ConfigureAwait(false); + await ctx.RespondAsync($"Hello, {ctx.User.Mention}", true).ConfigureAwait(false); else - await ctx.RespondAsync(":wave: Welcome " + member.Mention + " to " + ctx.Guild.Name + - ". Enjoy your stay!").ConfigureAwait(false); + await ctx.RespondAsync($"Welcome {member.Mention} to {ctx.Guild.Name}. Enjoy your stay!", true).ConfigureAwait(false); } #endregion COMMAND_HELLO + + #region COMMAND_TTS + + [Command("tts"), Aliases("echo", "repeat", "say", "talk")] + [Description("Make FlawBOT repeat a message as text-to-speech")] + public async Task Say(CommandContext ctx, + [Description("Message for the bot to repeat"), RemainingText] + string message) + { + if (string.IsNullOrWhiteSpace(message)) + await ctx.RespondAsync(":thinking:").ConfigureAwait(false); + else + await ctx.RespondAsync(Formatter.BlockCode(Formatter.Strip(message)), true).ConfigureAwait(false); + } + + #endregion COMMAND_TTS } } \ No newline at end of file diff --git a/src/FlawBOT/Modules/Misc/PollModule.cs b/src/FlawBOT/Modules/Misc/PollModule.cs index a6f6455e..7f23832e 100644 --- a/src/FlawBOT/Modules/Misc/PollModule.cs +++ b/src/FlawBOT/Modules/Misc/PollModule.cs @@ -25,7 +25,7 @@ public async Task Poll(CommandContext ctx, { if (string.IsNullOrWhiteSpace(question)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_POLL_QUESTION, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_POLL_QUESTION, ResponseType.Warning) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/AmiiboModule.cs b/src/FlawBOT/Modules/Search/AmiiboModule.cs index 5ce33048..53d741f6 100644 --- a/src/FlawBOT/Modules/Search/AmiiboModule.cs +++ b/src/FlawBOT/Modules/Search/AmiiboModule.cs @@ -24,7 +24,7 @@ public async Task GetAmiibo(CommandContext ctx, var results = await AmiiboService.GetAmiiboDataAsync(query).ConfigureAwait(false); if (results is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/DictionaryModule.cs b/src/FlawBOT/Modules/Search/DictionaryModule.cs index 4a1fd080..fd4735b4 100644 --- a/src/FlawBOT/Modules/Search/DictionaryModule.cs +++ b/src/FlawBOT/Modules/Search/DictionaryModule.cs @@ -25,7 +25,7 @@ public async Task UrbanDictionary(CommandContext ctx, var results = await DictionaryService.GetDictionaryDefinitionAsync(query).ConfigureAwait(false); if (results.ResultType == "no_results" || results.List.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/ImgurModule.cs b/src/FlawBOT/Modules/Search/ImgurModule.cs index bd457f0b..72fb5f2d 100644 --- a/src/FlawBOT/Modules/Search/ImgurModule.cs +++ b/src/FlawBOT/Modules/Search/ImgurModule.cs @@ -39,7 +39,7 @@ public async Task Imgur(CommandContext ctx, break; default: - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); break; } diff --git a/src/FlawBOT/Modules/Search/NASAModule.cs b/src/FlawBOT/Modules/Search/NASAModule.cs index dc9ec769..1688f1e3 100644 --- a/src/FlawBOT/Modules/Search/NASAModule.cs +++ b/src/FlawBOT/Modules/Search/NASAModule.cs @@ -20,7 +20,7 @@ public async Task Nasa(CommandContext ctx) var results = await NasaService.GetNasaImageAsync().ConfigureAwait(false); if (results is null) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_API_CONNECTION, EmbedType.Missing).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, Resources.ERR_API_CONNECTION, ResponseType.Missing).ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/NewsModule.cs b/src/FlawBOT/Modules/Search/NewsModule.cs index 8ed8716f..28d28f1c 100644 --- a/src/FlawBOT/Modules/Search/NewsModule.cs +++ b/src/FlawBOT/Modules/Search/NewsModule.cs @@ -24,7 +24,7 @@ public async Task News(CommandContext ctx, var results = await NewsService.GetNewsDataAsync(query).ConfigureAwait(false); if (results.Status != "ok") { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/OMDBModule.cs b/src/FlawBOT/Modules/Search/OMDBModule.cs index babb6f8b..9606fea2 100644 --- a/src/FlawBOT/Modules/Search/OMDBModule.cs +++ b/src/FlawBOT/Modules/Search/OMDBModule.cs @@ -24,7 +24,7 @@ public async Task Omdb(CommandContext ctx, var results = OmdbService.GetMovieListAsync(query.Replace(" ", "+")).Result; if (!results.Search.Any()) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/RedditModule.cs b/src/FlawBOT/Modules/Search/RedditModule.cs index 5055db60..1d37a48a 100644 --- a/src/FlawBOT/Modules/Search/RedditModule.cs +++ b/src/FlawBOT/Modules/Search/RedditModule.cs @@ -44,7 +44,7 @@ private static async Task RedditPost(CommandContext ctx, string query, RedditCat var results = RedditService.GetResults(query, category); if (results is null || results.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_COMMON, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_COMMON, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/TwitchModule.cs b/src/FlawBOT/Modules/Search/TwitchModule.cs index b2da67e4..0dd357ab 100644 --- a/src/FlawBOT/Modules/Search/TwitchModule.cs +++ b/src/FlawBOT/Modules/Search/TwitchModule.cs @@ -24,7 +24,7 @@ public async Task Twitch(CommandContext ctx, var results = await TwitchService.GetTwitchDataAsync(query).ConfigureAwait(false); if (results.Total == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_TWITCH, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_TWITCH, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/WikipediaModule.cs b/src/FlawBOT/Modules/Search/WikipediaModule.cs index cbfef423..e010933f 100644 --- a/src/FlawBOT/Modules/Search/WikipediaModule.cs +++ b/src/FlawBOT/Modules/Search/WikipediaModule.cs @@ -25,7 +25,7 @@ public async Task Wikipedia(CommandContext ctx, var results = WikipediaService.GetWikipediaDataAsync(query); if (results.Error != null || results.Search.Count == 0) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_WIKIPEDIA, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_WIKIPEDIA, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Search/WorldModule.cs b/src/FlawBOT/Modules/Search/WorldModule.cs index 398dffe8..afa17382 100644 --- a/src/FlawBOT/Modules/Search/WorldModule.cs +++ b/src/FlawBOT/Modules/Search/WorldModule.cs @@ -23,7 +23,7 @@ public async Task IpTrack(CommandContext ctx, { if (string.IsNullOrWhiteSpace(address) || !IPAddress.TryParse(address, out var ip)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_INVALID_IP, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.ERR_INVALID_IP, ResponseType.Missing) .ConfigureAwait(false); return; } @@ -31,7 +31,7 @@ await BotServices.SendEmbedAsync(ctx, Resources.ERR_INVALID_IP, EmbedType.Missin var results = WorldService.GetIpLocationAsync(ip).Result; if (results.Type == null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_LOCATION, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_LOCATION, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -58,7 +58,7 @@ public async Task Weather(CommandContext ctx, var results = await WorldService.GetWeatherDataAsync(query).ConfigureAwait(false); if (results is null) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_LOCATION, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_LOCATION, ResponseType.Missing) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Server/ChannelModule.cs b/src/FlawBOT/Modules/Server/ChannelModule.cs index 3f42a6ac..79152139 100644 --- a/src/FlawBOT/Modules/Server/ChannelModule.cs +++ b/src/FlawBOT/Modules/Server/ChannelModule.cs @@ -29,7 +29,7 @@ public async Task CreateCategory(CommandContext ctx, { if (!BotServices.CheckChannelName(name)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_NAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_NAME, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -100,7 +100,7 @@ public Task GetChannel(CommandContext ctx, // Check that the user has the permission in the channel to view its information if (!ctx.Member.PermissionsIn(channel).HasPermission(Permissions.AccessChannels)) - return BotServices.SendEmbedAsync(ctx, "You are not allowed to see this channel!", EmbedType.Warning); + return BotServices.SendResponseAsync(ctx, "You are not allowed to see this channel!", ResponseType.Warning); // Create the base embed message var output = new DiscordEmbedBuilder() @@ -165,7 +165,7 @@ public async Task SetChannelName(CommandContext ctx, { if (!BotServices.CheckChannelName(name)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_NAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_NAME, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -188,14 +188,14 @@ public async Task CreateText(CommandContext ctx, { if (!BotServices.CheckChannelName(name)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_NAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_NAME, ResponseType.Warning) .ConfigureAwait(false); return; } if (ctx.Guild.Channels.Any(chn => string.Equals(name, chn.Value.Name, StringComparison.OrdinalIgnoreCase))) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_EXISTS, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_EXISTS, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -218,7 +218,7 @@ public async Task SetChannelTopic(CommandContext ctx, { if (topic.Length > 1024) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_TOPIC, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_TOPIC, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -241,14 +241,14 @@ public async Task CreateVoice(CommandContext ctx, { if (!BotServices.CheckChannelName(name)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_NAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_NAME, ResponseType.Warning) .ConfigureAwait(false); return; } if (ctx.Guild.Channels.Any(chn => string.Equals(name, chn.Value.Name, StringComparison.OrdinalIgnoreCase))) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_CHANNEL_EXISTS, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_CHANNEL_EXISTS, ResponseType.Warning) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Modules/Server/EmojiModule.cs b/src/FlawBOT/Modules/Server/EmojiModule.cs index 5bc6af2f..7b172e3b 100644 --- a/src/FlawBOT/Modules/Server/EmojiModule.cs +++ b/src/FlawBOT/Modules/Server/EmojiModule.cs @@ -34,14 +34,14 @@ public async Task CreateEmoji(CommandContext ctx, { if (!ctx.Message.Attachments.Any() || !Uri.TryCreate(ctx.Message.Attachments[0].Url, UriKind.Absolute, out url)) - await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_IMAGE, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_EMOJI_IMAGE, ResponseType.Warning) .ConfigureAwait(false); return; } if (string.IsNullOrWhiteSpace(name) || name.Length < 2 || name.Length > 50) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_NAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_EMOJI_NAME, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -56,7 +56,7 @@ await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_NAME, EmbedType.Warnin { if (stream.Length >= 256000) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_SIZE, EmbedType.Warning).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, Resources.ERR_EMOJI_SIZE, ResponseType.Warning).ConfigureAwait(false); return; } var emoji = await ctx.Guild.CreateEmojiAsync(name, stream).ConfigureAwait(false); @@ -65,7 +65,7 @@ await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_NAME, EmbedType.Warnin } catch { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_ADD, EmbedType.Error).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, Resources.ERR_EMOJI_ADD, ResponseType.Error).ConfigureAwait(false); } } @@ -88,7 +88,7 @@ public async Task DeleteEmoji(CommandContext ctx, } catch (NotFoundException) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_EMOJI, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_EMOJI, ResponseType.Missing) .ConfigureAwait(false); } } @@ -108,7 +108,7 @@ public async Task EditEmoji(CommandContext ctx, { if (string.IsNullOrWhiteSpace(name)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_NAME, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_EMOJI_NAME, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -119,7 +119,7 @@ await BotServices.SendEmbedAsync(ctx, Resources.ERR_EMOJI_NAME, EmbedType.Warnin } catch (NotFoundException) { - await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_EMOJI, EmbedType.Missing) + await BotServices.SendResponseAsync(ctx, Resources.NOT_FOUND_EMOJI, ResponseType.Missing) .ConfigureAwait(false); } } diff --git a/src/FlawBOT/Modules/Server/RoleModule.cs b/src/FlawBOT/Modules/Server/RoleModule.cs index bf9a5a21..4b9e26f6 100644 --- a/src/FlawBOT/Modules/Server/RoleModule.cs +++ b/src/FlawBOT/Modules/Server/RoleModule.cs @@ -33,8 +33,8 @@ public async Task ColorRole(CommandContext ctx, var regex = new Regex("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", RegexOptions.Compiled).Match(color.ToString()); if (!regex.Success) { - await BotServices.SendEmbedAsync(ctx, "Invalid color code. Please enter a HEX color code like #E7B53B", - EmbedType.Warning).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, "Invalid color code. Please enter a HEX color code like #E7B53B", + ResponseType.Warning).ConfigureAwait(false); return; } @@ -59,7 +59,7 @@ public async Task CreateRole(CommandContext ctx, { if (string.IsNullOrWhiteSpace(role)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_NAME, EmbedType.Warning).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, Resources.ERR_ROLE_NAME, ResponseType.Warning).ConfigureAwait(false); return; } @@ -80,7 +80,7 @@ public async Task DeleteRole(CommandContext ctx, { if (role is null) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_ROLE_EXISTING, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -101,7 +101,7 @@ public async Task GetRole(CommandContext ctx, { if (role is null) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_ROLE_EXISTING, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -132,7 +132,7 @@ public async Task UsersInRole(CommandContext ctx, { if (role is null) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_ROLE_EXISTING, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -151,11 +151,11 @@ await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.War } if (usersList.Length == 0) - await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " has no members") + await BotServices.SendResponseAsync(ctx, Formatter.Bold(role.Name) + " has no members") .ConfigureAwait(false); else await BotServices - .SendEmbedAsync(ctx, Formatter.Bold(role.Name) + $" has **{userCount}** member(s): {usersList}") + .SendResponseAsync(ctx, Formatter.Bold(role.Name) + $" has **{userCount}** member(s): {usersList}") .ConfigureAwait(false); } @@ -174,13 +174,13 @@ public async Task MentionRole(CommandContext ctx, if (role.IsMentionable) { await role.ModifyAsync(mentionable: false).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **not-mentionable**") + await BotServices.SendResponseAsync(ctx, Formatter.Bold(role.Name) + " is now **not-mentionable**") .ConfigureAwait(false); } else { await role.ModifyAsync(mentionable: true).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **mentionable**") + await BotServices.SendResponseAsync(ctx, Formatter.Bold(role.Name) + " is now **mentionable**") .ConfigureAwait(false); } } @@ -219,13 +219,13 @@ public async Task RevokeAllRoles(CommandContext ctx, { if (!member.Roles.Any()) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_NONE, EmbedType.Warning).ConfigureAwait(false); + await BotServices.SendResponseAsync(ctx, Resources.ERR_ROLE_NONE, ResponseType.Warning).ConfigureAwait(false); return; } if (member.Roles.Max(r => r.Position) >= ctx.Member.Roles.Max(r => r.Position)) { - await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_NOT_ALLOWED, EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, Resources.ERR_ROLE_NOT_ALLOWED, ResponseType.Warning) .ConfigureAwait(false); return; } @@ -268,13 +268,13 @@ public async Task SidebarRole(CommandContext ctx, if (role.IsHoisted) { await role.ModifyAsync(hoist: false).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **hidden**") + await BotServices.SendResponseAsync(ctx, Formatter.Bold(role.Name) + " is now **hidden**") .ConfigureAwait(false); } else { await role.ModifyAsync(hoist: true).ConfigureAwait(false); - await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **displayed**") + await BotServices.SendResponseAsync(ctx, Formatter.Bold(role.Name) + " is now **displayed**") .ConfigureAwait(false); } } diff --git a/src/FlawBOT/Modules/Server/ServerModule.cs b/src/FlawBOT/Modules/Server/ServerModule.cs index e6f4a8d9..368cf06f 100644 --- a/src/FlawBOT/Modules/Server/ServerModule.cs +++ b/src/FlawBOT/Modules/Server/ServerModule.cs @@ -35,7 +35,7 @@ public async Task SetServerAvatar(CommandContext ctx, catch { await BotServices - .SendEmbedAsync(ctx, ctx.Guild.Name + " server avatar has not been updated!", EmbedType.Error) + .SendResponseAsync(ctx, ctx.Guild.Name + " server avatar has not been updated!", ResponseType.Error) .ConfigureAwait(false); } } @@ -102,7 +102,7 @@ public async Task Prune(CommandContext ctx, int days = 7) { if (days < 1 || days > 30) - await BotServices.SendEmbedAsync(ctx, "Number of days must be between 1 and 30", EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, "Number of days must be between 1 and 30", ResponseType.Warning) .ConfigureAwait(false); var count = await ctx.Guild.GetPruneCountAsync(days).ConfigureAwait(false); if (count == 0) @@ -136,7 +136,7 @@ public async Task SetServerName(CommandContext ctx, if (string.IsNullOrWhiteSpace(name) || name.Length > 100) { await BotServices - .SendEmbedAsync(ctx, "Server name cannot be blank or over 100 characters!", EmbedType.Warning) + .SendResponseAsync(ctx, "Server name cannot be blank or over 100 characters!", ResponseType.Warning) .ConfigureAwait(false); return; } @@ -169,7 +169,7 @@ public async Task Warn(CommandContext ctx, var dm = await member.CreateDmChannelAsync().ConfigureAwait(false); if (dm is null) { - await BotServices.SendEmbedAsync(ctx, "Unable to direct message this user", EmbedType.Warning) + await BotServices.SendResponseAsync(ctx, "Unable to direct message this user", ResponseType.Warning) .ConfigureAwait(false); return; } diff --git a/src/FlawBOT/Properties/Resources.Designer.cs b/src/FlawBOT/Properties/Resources.Designer.cs index afccc160..bde3d040 100644 --- a/src/FlawBOT/Properties/Resources.Designer.cs +++ b/src/FlawBOT/Properties/Resources.Designer.cs @@ -276,6 +276,15 @@ internal static string INFO_GIF_LOADING { } } + /// + /// Looks up a localized string similar to The following information will be sent to the developer for investigation: User ID, Server ID, Server Name and Server Owner Name.. + /// + internal static string INFO_REPORT_SENDER { + get { + return ResourceManager.GetString("INFO_REPORT_SENDER", resourceCulture); + } + } + /// /// Looks up a localized string similar to Request timed out.... /// diff --git a/src/FlawBOT/Properties/Resources.resx b/src/FlawBOT/Properties/Resources.resx index f5b5f33d..ae472f95 100644 --- a/src/FlawBOT/Properties/Resources.resx +++ b/src/FlawBOT/Properties/Resources.resx @@ -314,4 +314,7 @@ https://{0}.com/img/{1}/{2}.jpg + + The following information will be sent to the developer for investigation: User ID, Server ID, Server Name and Server Owner Name. + \ No newline at end of file diff --git a/src/FlawBOT/Services/Bot/BotService.cs b/src/FlawBOT/Services/Bot/BotService.cs index 3c0b2d15..217c5a7c 100644 --- a/src/FlawBOT/Services/Bot/BotService.cs +++ b/src/FlawBOT/Services/Bot/BotService.cs @@ -16,36 +16,17 @@ namespace FlawBOT.Services { public class BotServices { - public static async Task SendEmbedAsync(CommandContext ctx, string message, EmbedType type = EmbedType.Default) + public static async Task SendResponseAsync(CommandContext ctx, string message, ResponseType type = ResponseType.Default) { - var prefix = string.Empty; - DiscordColor color; - switch (type) + message = type switch { - case EmbedType.Warning: - prefix = ":warning: "; - color = DiscordColor.Yellow; - break; + ResponseType.Warning => ":exclamation: " + message, + ResponseType.Missing => ":mag: " + message, + ResponseType.Error => ":no_entry: " + message, + _ => message + }; - case EmbedType.Missing: - prefix = ":mag: "; - color = DiscordColor.Wheat; - break; - - case EmbedType.Error: - prefix = ":no_entry: "; - color = DiscordColor.Red; - break; - - default: - color = new DiscordColor("#00FF7F"); - break; - } - - var output = new DiscordEmbedBuilder() - .WithDescription(prefix + message) - .WithColor(color); - await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false); + await ctx.RespondAsync(message).ConfigureAwait(false); } public static async Task SendUserStateChangeAsync(CommandContext ctx, UserStateChange state, DiscordMember user, @@ -90,7 +71,7 @@ public static async Task CheckImageInput(CommandContext ctx, strin if (!Uri.TryCreate(input, UriKind.Absolute, out _) && (!input.EndsWith(".img") || !input.EndsWith(".png") || !input.EndsWith(".jpg"))) { - await SendEmbedAsync(ctx, Resources.URL_INVALID_IMG, EmbedType.Warning) + await SendResponseAsync(ctx, Resources.URL_INVALID_IMG, ResponseType.Warning) .ConfigureAwait(false); } else diff --git a/src/FlawBOT/Services/Bot/LavalinkService.cs b/src/FlawBOT/Services/Bot/LavalinkService.cs index 3fcaaf79..5edbcbd9 100644 --- a/src/FlawBOT/Services/Bot/LavalinkService.cs +++ b/src/FlawBOT/Services/Bot/LavalinkService.cs @@ -20,7 +20,7 @@ public LavalinkService(DiscordClient client) Discord = client; Discord.Ready += Client_Ready; _trackException = - new AsyncEvent("FLAWBOT_LAVALINK_TRACK_EXCEPTION", + new AsyncEvent($"{SharedData.Name.ToUpperInvariant()}_LAVALINK_TRACK_EXCEPTION", TimeSpan.Zero, EventExceptionHandler); } diff --git a/src/FlawBOT/Services/Search/YouTubeService.cs b/src/FlawBOT/Services/Search/YouTubeService.cs index b8034887..fe9c85c8 100644 --- a/src/FlawBOT/Services/Search/YouTubeService.cs +++ b/src/FlawBOT/Services/Search/YouTubeService.cs @@ -46,7 +46,7 @@ public async Task GetEmbeddedResults(string query, int amount, str Color = DiscordColor.Red }; results = results.Count > 25 ? results.Take(25).ToList() : results; - var output = new DiscordEmbedBuilder {Color = DiscordColor.Red}; + var output = new DiscordEmbedBuilder { Color = DiscordColor.Red }; foreach (var result in results) switch (result.Id.Kind) { @@ -90,11 +90,11 @@ public async Task> GetMusicDataAsync(string term) var uri = new Uri( $"https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=5&type=video&fields=items(id(videoId),snippet(title,channelTitle))&key={YouTube.ApiKey}&q={WebUtility.UrlEncode(term)}"); - var json = "{}"; + string json; Http.BaseAddress = new Uri("https://www.googleapis.com/youtube/v3/search"); Http.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", SharedData.Name); using (var req = await Http.GetAsync(uri)) - using (var res = await req.Content.ReadAsStreamAsync()) + await using (var res = await req.Content.ReadAsStreamAsync()) using (var sr = new StreamReader(res, Encoding.UTF8)) { json = await sr.ReadToEndAsync(); @@ -103,7 +103,7 @@ public async Task> GetMusicDataAsync(string term) var jsonData = JObject.Parse(json); var data = jsonData["items"].ToObject>(); - return data.Select(x => new YouTubeData(x.Snippet.Title, x.Snippet.Author, x.Id.VideoId)); + return data!.Select(x => new YouTubeData(x.Snippet.Title, x.Snippet.Author, x.Id.VideoId)); } } } \ No newline at end of file