/// <summary> /// Generates default command name->method pairs. /// </summary> void DefaultCommands(DiscordBot bot) { AdminCommands adminCmds = new AdminCommands(); MetaCommands metaCmds = new MetaCommands(); UtilityCommands utilCmds = new UtilityCommands(); CoreCommands coreCmds = new CoreCommands(IsBotCommander); // Informational bot.RegisterCommand(InfoCmds.CMD_Help, "help", "halp", "helps", "halps", "hel", "hal", "h"); bot.RegisterCommand(InfoCmds.CMD_Hello, "hello", "hi", "hey", "source", "src"); bot.RegisterCommand(InfoCmds.CMD_Info, "info", "notice", "alert"); bot.RegisterCommand(InfoCmds.CMD_Update, "update", "latest", "current", "build", "builds", "download", "version"); bot.RegisterCommand(InfoCmds.CMD_GitHub, "github", "git", "gh", "readme", "read", "link"); bot.RegisterCommand(InfoCmds.CMD_Issues, "issues", "issue", "error", "ghissues", "githubissues"); bot.RegisterCommand(InfoCmds.CMD_Rule, "rule", "rules"); bot.RegisterCommand(InfoCmds.CMD_Quote, "quote", "quotes", "q"); // Meta Docs bot.RegisterCommand(metaCmds.CMD_Command, "command", "commands", "cmd", "cmds", "c"); bot.RegisterCommand(metaCmds.CMD_Mechanism, "mechanism", "mechanisms", "mech", "mechs", "mec", "mecs", "m"); bot.RegisterCommand(metaCmds.CMD_Tag, "tag", "tags", "t"); bot.RegisterCommand(metaCmds.CMD_Event, "event", "events", "evt", "evts", "e"); bot.RegisterCommand(metaCmds.CMD_Action, "action", "actions", "act", "acts", "a"); bot.RegisterCommand(metaCmds.CMD_Language, "language", "languages", "lang", "langs", "l"); bot.RegisterCommand(metaCmds.CMD_Guide, "guide", "guides", "g", "beginner", "beginners", "beginnersguide", "guidepage", "guidespage"); bot.RegisterCommand(metaCmds.CMD_Search, "search", "s", "find", "f", "get", "locate", "what", "where", "how", "w", "meta", "metainfo", "docs", "doc", "documentation", "documentations", "document", "documents"); // Utility bot.RegisterCommand(utilCmds.CMD_LogCheck, "logcheck", "checklog", "logscheck", "checklogs"); bot.RegisterCommand(utilCmds.CMD_VersionCheck, "versioncheck", "checkversion", "iscurrent", "isuptodate", "isupdated", "checkcurrent", "currentcheck"); bot.RegisterCommand(utilCmds.CMD_ScriptCheck, "script", "scriptcheck", "dscript", "ds", "checkscript", "dscriptcheck", "checkdscript"); // Admin bot.RegisterCommand(coreCmds.CMD_Restart, "restart"); bot.RegisterCommand(adminCmds.CMD_Reload, "reload"); }
/// <summary> /// Generates default command name->method pairs. /// </summary> void DefaultCommands() { InfoCmds.Bot = this; AdminCommands adminCmds = new AdminCommands() { Bot = this }; MetaCommands metaCmds = new MetaCommands() { Bot = this }; UtilityCommands utilCmds = new UtilityCommands() { Bot = this }; // Informational RegisterCommand(InfoCmds.CMD_Help, "help", "halp", "helps", "halps", "hel", "hal", "h"); RegisterCommand(InfoCmds.CMD_Hello, "hello", "hi", "hey", "source", "src"); RegisterCommand(InfoCmds.CMD_Info, "info", "notice", "alert"); RegisterCommand(InfoCmds.CMD_Update, "update", "latest", "current", "build", "builds", "download", "version"); RegisterCommand(InfoCmds.CMD_GitHub, "github", "git", "gh", "readme", "read", "link"); RegisterCommand(InfoCmds.CMD_Issues, "issues", "issue", "error", "ghissues", "githubissues"); RegisterCommand(InfoCmds.CMD_Rule, "rule", "rules"); // Meta Docs RegisterCommand(metaCmds.CMD_Command, "command", "commands", "cmd", "cmds", "c"); RegisterCommand(metaCmds.CMD_Mechanism, "mechanism", "mechanisms", "mech", "mechs", "mec", "mecs", "m"); RegisterCommand(metaCmds.CMD_Tag, "tag", "tags", "t"); RegisterCommand(metaCmds.CMD_Event, "event", "events", "evt", "evts", "e"); RegisterCommand(metaCmds.CMD_Action, "action", "actions", "act", "acts", "a"); RegisterCommand(metaCmds.CMD_Language, "language", "languages", "lang", "langs", "l"); RegisterCommand(metaCmds.CMD_Search, "search", "s", "find", "f", "get", "g", "locate", "what", "where", "how", "w", "meta", "metainfo", "docs", "doc", "documentation", "documentations", "document", "documents"); // Utility // TODO: CMD_DScriptCheck RegisterCommand(utilCmds.CMD_LogCheck, "logcheck", "checklog", "logscheck", "checklogs"); RegisterCommand(utilCmds.CMD_VersionCheck, "versioncheck", "checkversion", "iscurrent", "isuptodate", "isupdated", "checkcurrent", "currentcheck"); // Admin RegisterCommand(adminCmds.CMD_Restart, "restart"); RegisterCommand(adminCmds.CMD_Reload, "reload"); }
/// <summary> /// Handles a search for Denizen meta. /// </summary> /// <typeparam name="T">The meta type.</typeparam> /// <param name="searchInput">The search input.</param> /// <param name="command">The command that initiated this search.</param> /// <param name="listOnly">Whether to only allow a list of results, rather than replying with exact or only matches.</param> /// <returns>Whether any results were found.</returns> public async Task HandleSearch <T>(string searchInput, BotCommand command, bool listOnly = false) where T : IDenizenMetaType { searchInput = searchInput.ToLower(); if (string.IsNullOrWhiteSpace(searchInput)) { return; } if (searchInput == "all") { string allOf = typeof(T) == typeof(IDenizenMetaType) ? "meta" : (Meta.KnownMetaTypeNames[typeof(T)] + "s"); List <Embed> pages = command.Bot.Meta.AllOf <T>().Paginate((tag) => tag.GetListString()) .Select((page) => new EmbedBuilder().WithColor(Color.Gold).WithTitle("All known " + allOf).WithDescription(page).Build()) .ToList(); await command.ReplyAsync(new DiscordPaginatedMessage(pages)); return; } if (searchInput.StartsWith('\\')) { searchInput = searchInput.Substring(1); } IEnumerable <SearchResult <T> > results = Meta.Search <T>(searchInput).OrderByDescending((x) => x.MatchLevel); SearchResult <T> first = results.FirstOrDefault(); if (first.Result == null) { Type type = typeof(T); string error; if (type == typeof(IDenizenMetaType)) { error = "Nothing was found matching the specified input. :pensive:"; } else { error = "No " + Meta.KnownMetaTypeNames[typeof(T)] + "s were found matching the specified input. :pensive:"; } await command.ReplyAsync(new DiscordEmbedMessage(new EmbedBuilder().WithColor(Color.Red).WithDescription(error).Build())); return; } else if (!listOnly && (first.MatchLevel == SearchMatchLevel.EXACT || results.ElementAtOrDefault(1).Result == null)) { await command.ReplyAsync(new DenizenMetaMessage(first.Result, first.MatchLevel)); return; } else { List <Embed> pages = new List <Embed>(); EmbedBuilder builder = new EmbedBuilder().WithColor(Color.Gold); SearchMatchLevel lastLevel = SearchMatchLevel.NONE; EmbedFieldBuilder field = null; string value = string.Empty; int length = 0; int pageLength = 0; foreach (SearchResult <T> result in results) { if (result.MatchLevel != lastLevel) { if (field != null) { builder.AddField(field.WithValue(value.Substring(0, length - 2))); pageLength += length; value = string.Empty; length = 0; } field = new EmbedFieldBuilder().WithName(MetaCommands.AdaptMatchLevelPlural(result.MatchLevel)); lastLevel = result.MatchLevel; if (pageLength > 1250) { pages.Add(builder.Build()); builder = new EmbedBuilder().WithColor(Color.Gold); } } string next = result.Result.GetListString() + ", "; int newLength = next.Length + length; if (newLength > 1000 || newLength + pageLength > 1500) { builder.AddField(field.WithValue(value.Substring(0, length - 2))); pages.Add(builder.Build()); builder = new EmbedBuilder().WithColor(Color.Gold); field = new EmbedFieldBuilder().WithName(MetaCommands.AdaptMatchLevelPlural(result.MatchLevel) + " [Continued]"); pageLength = 0; value = next; length = next.Length; } else { value += next; length = newLength; } } builder.AddField(field.WithValue(value.Substring(0, length - 2))); pages.Add(builder.Build()); await command.ReplyAsync(new DiscordPaginatedMessage(pages)); return; } }
/// <summary> /// Creates a new paginated message from meta information. /// </summary> /// <param name="meta">The meta to paginate.</param> /// <returns>A new paginated message.</returns> public DiscordPaginatedMessage GetPaginatedMeta(DenizenMetaMessage meta) { List <Embed> pages = new List <Embed>(); string title = MetaCommands.AdaptMatchLevel(meta.MatchLevel) + " - " + Bot.Meta.KnownMetaTypeNames[meta.Meta.GetType()]; EmbedBuilder builder = new EmbedBuilder().WithColor(Color.Green).WithTitle(title); foreach (MetaPropertyAttribute property in Bot.Meta.MetaTypeProperties[meta.Meta.GetType()].Values.OrderBy((x) => x.Position)) { object propertyValue = property.PropertyInfo.GetValue(meta.Meta); if (propertyValue == null) { continue; } if (property.ForceNextPage) { AddPage(ref pages, ref builder, title); } if (propertyValue is SingleObject <string> single) { string value = single.Value; if (string.IsNullOrEmpty(value)) { continue; } if (property.Code) { value = $"```{property.CodeExtension}\n{value}\n```"; } else { value = Regex.Replace(value, "<@link [^\\s]+ ([^>]+)>", "$1"); } if (value.Length > 1000) { int pos = 0; int remaining = value.Length; int nextLength = 1000; bool inCode = false; string current; do { current = value.Substring(pos, nextLength); if (nextLength >= 1000) { int cut = current.LastIndexOf('\n'); if (cut == -1) { cut = current.LastIndexOf(' '); } current = current.Substring(0, cut + 1); } pos += current.Length; remaining -= current.Length; nextLength = remaining > 1000 ? 1000 : remaining; ParseCode(ref current, ref inCode, property.CodeExtension); builder.AddField(new EmbedFieldBuilder().WithName(property.Display + (pos > 1000 ? " [Continued]" : "")).WithValue(current)); AddPage(ref pages, ref builder, title); }while (remaining > 0); } else { bool inCode = false; ParseCode(ref value, ref inCode, property.CodeExtension); builder.AddField(new EmbedFieldBuilder().WithName(property.Display).WithValue(value).WithIsInline(property.Inline)); } } else if (propertyValue is ListObject <string> list) { int count = 0; int total = 0; foreach (string current in list) { string value = current; count++; total++; if (property.Code) { value = $"```{property.CodeExtension}\n{value}\n```"; } builder.AddField(new EmbedFieldBuilder().WithName(property.Display + " #" + total).WithValue(value).WithIsInline(property.Inline)); if (count == property.PerPage) { AddPage(ref pages, ref builder, title); count = 0; } } } } if (builder.Fields.Count > 0) { pages.Add(builder.Build()); } return(new DiscordPaginatedMessage(pages)); }