From 18f4a82c78bc2062001c3b2ba7fecd64084808e1 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 22 Sep 2020 22:05:01 +0200 Subject: [PATCH] Add Embed support for CustomCommands --- .../Discord/Services/CustomCommandHandler.cs | 20 ++++- ChaosBot/Models/CustomCommand.cs | 3 +- .../CustomCommandEmbedBuilderFacade.cs | 80 +++++++++++++++++++ .../ProgrammingLanguageInterpreterFacade.cs | 9 ++- 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 ChaosBot/Services/CustomCommandEmbedBuilderFacade.cs diff --git a/ChaosBot/Discord/Services/CustomCommandHandler.cs b/ChaosBot/Discord/Services/CustomCommandHandler.cs index c406ac8..50b77b4 100644 --- a/ChaosBot/Discord/Services/CustomCommandHandler.cs +++ b/ChaosBot/Discord/Services/CustomCommandHandler.cs @@ -2,8 +2,11 @@ using System; using System.Linq; using System.Threading.Tasks; using ChaosBot.Models; +using ChaosBot.Services; using ChaosBot.Services.ProgrammingLanguageInterpreter; +using Discord; using Discord.Commands; +using Neo.IronLua; namespace ChaosBot.Discord.Services { @@ -29,10 +32,23 @@ namespace ChaosBot.Discord.Services { await context.Channel.SendMessageAsync(customCommand.Content); } + else if(customCommand.Type == CustomCommandType.CustomLua) + { + if (!ProgrammingLanguageInterpreterFacade.TryInterpret(customCommand, out string errorReason)) + throw new Exception($"Could not execute code: {errorReason}"); + } + else if (customCommand.Type == CustomCommandType.Embed) + { + EmbedBuilder embedBuilder = new EmbedBuilder(); + + CustomCommandEmbedBuilderFacade.SetDetails(embedBuilder, customCommand.Content); + + Embed embed = embedBuilder.Build(); + await context.Channel.SendMessageAsync(embed: embed); + } else { - if (!ProgrammingLanguageInterpreterFacade.TryInterpret(customCommand)) - throw new NotImplementedException($"No support for command type ${customCommand.Type}"); + throw new NotImplementedException($"No support for command type ${customCommand.Type}"); } return true; diff --git a/ChaosBot/Models/CustomCommand.cs b/ChaosBot/Models/CustomCommand.cs index 3bc0e94..a389e0c 100644 --- a/ChaosBot/Models/CustomCommand.cs +++ b/ChaosBot/Models/CustomCommand.cs @@ -23,6 +23,7 @@ namespace ChaosBot.Models public enum CustomCommandType { Basic = 0, - CustomLua = 1 + CustomLua = 1, + Embed = 2 } } diff --git a/ChaosBot/Services/CustomCommandEmbedBuilderFacade.cs b/ChaosBot/Services/CustomCommandEmbedBuilderFacade.cs new file mode 100644 index 0000000..c88e566 --- /dev/null +++ b/ChaosBot/Services/CustomCommandEmbedBuilderFacade.cs @@ -0,0 +1,80 @@ +using System; +using System.Text; +using System.Text.RegularExpressions; +using ChaosBot.Models; +using Discord; + +namespace ChaosBot.Services +{ + public static class CustomCommandEmbedBuilderFacade + { + public static void SetDetails(EmbedBuilder embedBuilder, string customCommandContent) + { + StringBuilder descriptionBuilder = new StringBuilder(); + + foreach (string line in customCommandContent.Split("\n")) + { + string prefix = "#"; + if (line.StartsWith(prefix)) + { + // This may require special treatment + string remainder = line.Substring(prefix.Length); + string pattern = @"^<([a-z]+)>(.+)<\/([a-z]+)>$"; + Match match = Regex.Match(remainder, pattern); + + // Ensure that there is some sort of match and that opening and closing tags are equal + if (match.Value == string.Empty || match.Groups[1] == match.Groups[3]) + { + DealWithNonSpecialLine(descriptionBuilder, line); + } + else + { + string tag = match.Groups[1].Value; + string data = match.Groups[2].Value; + switch (tag) + { + case "color": + string colorPattern = @"^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})"; + Match colorMatch = Regex.Match(data, colorPattern); + if (colorMatch.Value == string.Empty) + { + DealWithNonSpecialLine(descriptionBuilder, line); + } + else + { + int r = int.Parse(colorMatch.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); + int g = int.Parse(colorMatch.Groups[2].Value, System.Globalization.NumberStyles.HexNumber); + int b = int.Parse(colorMatch.Groups[3].Value, System.Globalization.NumberStyles.HexNumber); + + embedBuilder.Color = new Color(r, g, b); + } + break; + case "image": + embedBuilder.ImageUrl = data; + break; + case "title": + embedBuilder.Title = data; + break; + default: + DealWithNonSpecialLine(descriptionBuilder, line); + break; + } + } + } + else + { + // There is definitely no special treatment + DealWithNonSpecialLine(descriptionBuilder, line); + } + } + + embedBuilder.Description = descriptionBuilder.ToString(); + } + + private static void DealWithNonSpecialLine(StringBuilder descriptionBuilder, string line) + { + // Possible todo: escape mentions or something? + descriptionBuilder.AppendLine(line); + } + } +} diff --git a/ChaosBot/Services/ProgrammingLanguageInterpreter/ProgrammingLanguageInterpreterFacade.cs b/ChaosBot/Services/ProgrammingLanguageInterpreter/ProgrammingLanguageInterpreterFacade.cs index 3746908..b327ebc 100644 --- a/ChaosBot/Services/ProgrammingLanguageInterpreter/ProgrammingLanguageInterpreterFacade.cs +++ b/ChaosBot/Services/ProgrammingLanguageInterpreter/ProgrammingLanguageInterpreterFacade.cs @@ -4,11 +4,16 @@ namespace ChaosBot.Services.ProgrammingLanguageInterpreter { public static class ProgrammingLanguageInterpreterFacade { - public static bool TryInterpret(CustomCommand customCommand) + public static bool TryInterpret(CustomCommand customCommand, out string errorReason) { + errorReason = ""; IProgrammingLanguageInterpreter interpreter = ProgrammingLanguageInterpreterFactory.GetInterpreter(customCommand.Type); - if (interpreter == null) return false; + if (interpreter == null) + { + errorReason = "Could not set up an interpreter for the code"; + return false; + } interpreter.Interpret(customCommand.Content, customCommand.Command); return true;