public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length == 0) { string text = "Current Archon Commands:\n```\n"; foreach (ArchonCommand cmd in CommandMarshaller.ArchonCommands) { text += cmd.Name + "\n"; } text += "```\n"; await ResponseUtil.RespondToAsync(originalMessage, text); } else if (args.Length == 1) { string command = args[0]; foreach (ArchonCommand cmd in CommandMarshaller.ArchonCommands) { if (cmd.Name.ToLower() == command.ToLower()) { string text = string.Format("**Archon Command:** `{0}` \n{1}\n\n**Usage:** `{2}`", cmd.Name, cmd.Description, cmd.Syntax); await ResponseUtil.RespondToAsync(originalMessage, text); return; } } throw new ArchonCommandException(this, $"Archon Command `{command}` does not exist."); } else { throw new ArchonCommandException(this, "Invalid argument count. Expected no arguments, or one argument which is the name of the archon command you wish to get details on."); } }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length != 2) { throw new CommandException(this, "Invalid argument count! Expected a user ID and a permission level."); } else { XanBotMember member = await UserGetter.GetMemberFromDataIDStrictAsync(context.Server, args[0]); byte permLvl = byte.Parse(args[1]); if (member == null) { throw new CommandException(this, "The specified member could not be found. Are you searching by user ID?"); } if (executingMember == member) { throw new CommandException(this, "You cannot alter your own permission level."); } if (executingMember.PermissionLevel <= permLvl) { throw new CommandException(this, string.Format("You cannot set the permission level of user `{0}` to a permission level equal to or higher than your own.", member.FullName)); } if (executingMember.PermissionLevel <= member.PermissionLevel) { // Trying to edit the permission level of someone higher than or equal to themselves. throw new CommandException(this, "You cannot edit the permission level of someone at a rank greater than or equal to your own."); } member.PermissionLevel = permLvl; await ResponseUtil.RespondToAsync(originalMessage, string.Format("Set the permission level of user `{0}` to `{1}`", member.FullName, permLvl.ToString())); } }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length != 2) { throw new ArchonCommandException(this, "Expected 2 args."); } if (context == null) { XanBotLogger.WriteLine(ORANGE + "For lack of any proper context (since this was run in the console), this member's permission level will be updated in ALL contexts."); XanBotLogger.WriteLine(ORANGE + "Are you sure you want to do this? [y/N]"); ConsoleKeyInfo key = Console.ReadKey(true); if (key.KeyChar != 'y') { XanBotLogger.WriteLine(ORANGE + "Cancelling operation."); return; } XanBotLogger.WriteLine("§aProcessing..."); foreach (BotContext ctx in BotContextRegistry.AllContexts) { if (!ctx.Virtual) { await SetPermissionInContext(ctx, args); } } XanBotLogger.WriteLine("§aDone."); return; } await SetPermissionInContext(context, args); await ResponseUtil.RespondToAsync(originalMessage, $"The permission level of user `{executingMember.FullName}` has been forced to {args[1]}."); }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length == 0) { string res = "```\n"; foreach (PassiveHandler handler in context.Handlers) { // Secret handlers can't be displayed in normal command usage. Only display handlers if they aren't secret, or if they are secret, only allow it in the mod channel. res += handler.Name + "\n"; } res += "```"; await ResponseUtil.RespondToAsync(originalMessage, res); } else if (args.Length == 1) { foreach (PassiveHandler handler in context.Handlers) { if (args[0].ToLower() == handler.Name.ToLower()) { // Same thing as above: Prevent users from getting info on secret handlers unless the command is executed in the bot channel. await ResponseUtil.RespondToAsync(originalMessage, "**" + handler.Name + ":** " + handler.Description); return; } } await ResponseUtil.RespondToAsync(originalMessage, "There is no Passive Handler with the name " + args[0] + "\n(If there's a space in the name, try adding quotation marks around the name!)"); } else { throw new CommandException(this, "Invalid amount of command arguments. Try putting quotation marks around the name of the handler."); } }
private async Task SetPermissionInContext(BotContext context, string[] args) { XanBotMember person = await UserGetter.GetMemberFromDataIDStrictAsync(context.Server, args[0]); if (person == null) { throw new ArchonCommandException(this, "Invalid user."); } if (person == context.Bot) { throw new ArchonCommandException(this, "My permission level is immutable and cannot be lowered from 255."); } if (byte.TryParse(args[1], out byte newLvl)) { person.PermissionLevel = newLvl; } else { if (decimal.TryParse(args[1], out decimal value)) { throw new ArchonCommandException(this, "Invalid permission level. The specified value is out of the acceptable range of values for a byte (0 to 255)."); } else { throw new ArchonCommandException(this, "Invalid permission level. Could not cast the input data into a byte value."); } } }
/// <summary> /// Returns whether or not the specified member can use the command. The default behavior checks if <paramref name="member"/>.PermissionLevel is greater than or equal to this command's <see cref="RequiredPermissionLevel"/>. /// </summary> /// <param name="member">The member using this command.</param> /// <returns>true if the specified member can use the command, false if they can not.</returns> public virtual UsagePermissionPacket CanUseCommand(XanBotMember member) { return(new UsagePermissionPacket( member.PermissionLevel >= RequiredPermissionLevel, $"You are not authorized to use {Name}. It is only available to Permission Level {RequiredPermissionLevel} (your Permission Level is {member.PermissionLevel})." )); }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (executingMember != null && executingMember.PermissionLevel < 254) { throw new ArchonCommandException(this, "Cannot execute this command at current permission level. This command requires backend console access (permission level 254+)"); } if (args.Length != 1) { throw new ArchonCommandException(this, "Expected one arg `<enabled>`."); } if (bool.TryParse(args[0], out bool enable)) { XanBotLogger.ShowDebugMessagesAnyway = enable; if (XanBotCoreSystem.IsDebugMode) { await ResponseUtil.RespondToAsync(originalMessage, "Forcefully " + (enable ? "ENABLING" : "DISABLING") + " debug-logging to the bot's console. **NOTE:** This will have no effect since the bot is currently running in debug mode."); return; } await ResponseUtil.RespondToAsync(originalMessage, "Forcefully " + (enable ? "ENABLING" : "DISABLING") + " debug-logging to the bot's console."); } else { throw new ArchonCommandException(this, $"Failed to cast `{args[0]}` into boolean (true/false)."); } }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (originalMessage != null) { await ResponseUtil.RespondToAsync(originalMessage, "Sending shutdown signal and shutting down..."); } XanBotCoreSystem.Exit(); }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (context == null) { throw new ArchonCommandException(this, "Cannot use currentcontext from the console, as it requires an instance of BotContext to be present."); } //ResponseUtil.RespondTo(originalMessage, context.ToStringForDiscordMessage()); //originalMessage?.RespondAsync(embed: context.ToEmbed()); await ResponseUtil.RespondToAsync(originalMessage, context); }
public override async Task <bool> RunHandlerAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage) { if (originalMessage.Content.ToLower().Contains("i'm gonna say the n word")) { await ResponseUtil.RespondToAsync(originalMessage, "THAT'S RACIST YOU CAN'T SAY THE N WORD!!!"); return(true); // We handled this message and don't want other handlers to intercept it. } return(false); // We did not handle this message so we can allow other handlers to intercept it. }
/// <summary> /// Stores the set permission level of this user for the sake of data persistence. This is internal since it is called whenever the property <see cref="XanBotMember.PermissionLevel"/> is set, and should not be called by users. /// </summary> /// <param name="member">The member to set in the internal cache.</param> /// <param name="saveToFileNow">If true, the config file for this context's user permissions will be set.</param> internal static void UpdatePermissionLevelOfMember(XanBotMember member, bool saveToFileNow = false) { if (!PermissionsInContext.ContainsKey(member.Context)) { PermissionsInContext[member.Context] = new Dictionary <ulong, byte>(); } PermissionsInContext[member.Context][member.Id] = member.PermissionLevel; if (saveToFileNow) { SaveContextPermissionsToFile(member.Context); } }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length == 0) { throw new CommandException(this, "Invalid argument count. Expected at least one arg."); } string subCommand = args[0]; args = args.Skip(1).ToArray(); foreach (ArchonCommand cmd in CommandMarshaller.ArchonCommands) { if (cmd.Name.ToLower() == subCommand.ToLower()) { await cmd.ExecuteCommandAsync(context, executingMember, originalMessage, args, allArgs); return; } } throw new CommandException(this, "Unable to execute Archon Command `" + subCommand + "` because it does not exist."); }
/// <summary> /// Runs the <see cref="PassiveHandler"/>s for the server that <paramref name="originalMessage"/> was sent in based on the content from the message. /// </summary> /// <param name="originalMessage">The chat message.</param> public static async Task RunPassiveHandlersForMessage(DiscordMessage originalMessage) { BotContext targetContext = BotContextRegistry.GetContext(originalMessage.Channel.Guild); XanBotMember sender = XanBotMember.GetMemberFromUser(targetContext, originalMessage.Author); if (!targetContext.Virtual) { foreach (PassiveHandler handler in targetContext.Handlers) { XanBotLogger.WriteDebugLine(handler.Name); if (await handler.RunHandlerAsync(targetContext, sender, originalMessage)) { XanBotLogger.WriteDebugLine("... returned true"); return; } XanBotLogger.WriteDebugLine("... returned false"); } } else { XanBotLogger.WriteDebugLine("Target context is virtual. Skipping passive handlers."); } }
/// <summary> /// Strictly gets a user from their user ID. Unlike <see cref="GetMemberFromDataAsync(DiscordGuild, string)"/>, this code will return null if a name or discriminator is passed in. /// </summary> /// <param name="data">The query to get a XanBotMember from. This can either be a ulong as a string or a user ping (<@ulong>)</param> /// <returns></returns> public static async Task <XanBotMember> GetMemberFromDataIDStrictAsync(DiscordGuild server, string data) { string newdata = data; if (data.StartsWith("<@") && data.EndsWith(">")) { newdata = data.Substring(2, data.Length - 3); } if (ulong.TryParse(newdata, out ulong uuid)) { DiscordUser user = await XanBotCoreSystem.Client.GetUserAsync(uuid); // Catch case: Someone's username is a bunch of numbers OR they link a user ID that isn't in the server. if (user != null) { XanBotMember member = XanBotMember.GetMemberFromUser(server, user); if (member != null) { return(member); } } } return(null); }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length == 0) { // User wants to get their own permissions. await ResponseUtil.RespondToAsync(originalMessage, string.Format("Your permission level is `{0}`", executingMember.PermissionLevel)); } else if (args.Length >= 1) { try { XanBotMember member = await UserGetter.GetMemberFromDataAsync(context.Server, allArgs); if (member == null) { throw new CommandException(this, "The specified user is not a member of this server."); } await ResponseUtil.RespondToAsync(originalMessage, string.Format("The permission level of `{0}` is `{1}`", member.FullName, member.PermissionLevel)); } catch (NonSingularResultException err) { string msg = err.Message; msg += "\nThe potential users are:\n"; foreach (XanBotMember member in err.PotentialReturnValues) { msg += member?.FullName + "(User GUID: " + member?.BaseUser.Id + ")\n"; } msg += "\nYou can directly copy/paste the user's GUID into this command to get that specific user."; if (msg.Length > 2000) { msg = err.Message + "\n\nUnfortunately, the list of potential users was too large to fit into a message."; } await ResponseUtil.RespondToAsync(originalMessage, msg); } } }
/// <summary> /// Handles a command issued via a Discord message. This does not test if it is a command. Please test with <see cref="IsCommand(string)"/> before running this. /// </summary> /// <param name="originalMessage">The Discord message sent by the command.</param> public static async Task HandleMessageCommand(DiscordMessage originalMessage) { DiscordUser author = originalMessage.Author; BotContext commandContext = BotContextRegistry.GetContext(originalMessage.Channel.Guild); XanBotLogger.WriteDebugLine("Executing command in bot context. Info:"); XanBotLogger.WriteLine(commandContext.ToConsoleString(), isDebugModeOnly: true); XanBotMember member = XanBotMember.GetMemberFromUser(commandContext, author); string text = originalMessage.Content; if (text.ToLower().StartsWith(CommandPrefix.ToLower())) { text = text.Substring(CommandPrefix.Length); } while (AllowSpacesAfterPrefix && text.StartsWith(" ")) { text = text.Substring(1); } string[] allArgs = ArgumentSplitter.SplitArgs(text); string command = allArgs[0]; string[] args = new string[0]; if (allArgs.Length > 1) { args = allArgs.Skip(1).ToArray(); } // Catch case: Prevent excessive command length. if (command.Length > 32) { await ResponseUtil.RespondToAsync(originalMessage, "The command you input is too long."); XanBotLogger.WriteLine(string.Format("§aUser \"§6{0}§a\" issued a command that was considered too long to parse.", member.FullName)); return; } // Catch case: Strip color formatting command.Replace(XanBotLogger.COLOR_CODE_SYM.ToString(), ""); XanBotLogger.WriteDebugLine("Searching for command..."); Command execCommand = null; string cmdLower = command.ToLower(); // Search the context FIRST. That ensures that context commands can override stock commands. foreach (Command cmd in commandContext.Commands) { if (cmd.Name.ToLower() == cmdLower) { execCommand = cmd; XanBotLogger.WriteDebugLine($"Found command [{cmd.Name}] in context."); break; } else { if (cmd.AlternateNames != null) { foreach (string altName in cmd.AlternateNames) { if (altName.ToLower() == cmdLower) { execCommand = cmd; break; } } } } } if (execCommand == null) { foreach (Command cmd in Commands) { if (cmd.Name.ToLower() == command.ToLower()) { execCommand = cmd; XanBotLogger.WriteDebugLine($"Found command [{cmd.Name}] globally."); break; } } } if (execCommand != null) { UsagePermissionPacket usagePerms = execCommand.CanUseCommand(member); if (usagePerms.CanUse) { if (execCommand.CanUseCommandInThisChannel(member, originalMessage.Channel, out DiscordChannel optimalTargetChannel)) { try { string allArgsText = ""; if (args.Length > 0) { allArgsText = text.Substring(command.Length + 1); } originalMessage.Channel.TriggerTypingAsync().GetAwaiter().GetResult(); await execCommand.ExecuteCommandAsync(commandContext, member, originalMessage, args, allArgsText); XanBotLogger.WriteLine(string.Format("§aUser \"§6{0}§a\" issued command \"§6{1}§a\" with args {2}", member.FullName, command, ArrayToText(args))); } catch (CommandException commandErr) { string message = string.Format("§cFailed to issue command `{0}`: §1{1}", commandErr.Command.Name, commandErr.Message); await ResponseUtil.RespondToAsync(originalMessage, message); XanBotLogger.WriteLine(string.Format("§aUser \"§6{0}§a\" attempted to issue command \"§6{1}§a\" but it failed. The command gave the reason: §2{2}", member.FullName, commandErr.Command.Name, commandErr.Message)); } catch (ArchonCommandException commandErr) { string message = string.Format("§cFailed to issue Archon Command `{0}`: §1{1}", commandErr.Command.Name, commandErr.Message); await ResponseUtil.RespondToAsync(originalMessage, message); XanBotLogger.WriteLine(string.Format("§aUser \"§6{0}§a\" attempted to issue Archon Command \"§6{1}§a\" but it failed. The command gave the reason: §2{2}", member.FullName, commandErr.Command.Name, commandErr.Message)); } catch (TaskCanceledException taskCancel) { XanBotLogger.WriteException(taskCancel); } } else { string message = string.Format($"You can't use this command here. Go to <#{optimalTargetChannel.Id}> instead."); await ResponseUtil.RespondToAsync(originalMessage, message); } } else { //string message = string.Format("You are not authorized to use `{0}`. It is only available to permission level `{1}` and above (You are at `{2}`)", execCommand.Name, execCommand.RequiredPermissionLevel, member.PermissionLevel); await ResponseUtil.RespondToAsync(originalMessage, usagePerms.ErrorMessage); XanBotLogger.WriteLine(string.Format("§aUser \"§6{0}§a\" attempted to issue command \"§6{1}§a\" but it failed because they don't have a high enough permission level or because the command's CanUseCommand method returned false.", member.FullName, execCommand.Name)); } } else { await ResponseUtil.RespondToAsync(originalMessage, "The command `" + command + "` does not exist."); XanBotLogger.WriteLine(string.Format("§aUser \"§6{0}§a\" attempted to issue command \"§6{1}§a\" but it failed because it doesn't exist.", member.FullName, command)); } }
/// <summary> /// Attempts to get a member via three distinct methods: <para/> /// First, it will attempt to cast <paramref name="data"/> into a ulong and see if it is a user GUID (this includes processing pings, like <@GUID_HERE>)<para/> /// Second, it will attempt to see if <paramref name="data"/> is a discriminator (only if data is formatted as #XXXX where XXXX is four digits)<para/> /// Finally, and only if the second method had no results or wasn't used, it will attempt to find <paramref name="data"/> as a nickname or username.<para/> /// This will throw a NonSingularResultException if the query can return more than one user. /// </summary> /// <param name="server">The Discord server to target.</param> /// <param name="data">The query to get a XanBotMember from. This can be a ulong as a string, a user ping (<@ulong>), a server nickname, a username (or optionally username#discriminator)</param> /// <exception cref="NonSingularResultException"/> /// <returns></returns> public static async Task <XanBotMember> GetMemberFromDataAsync(DiscordGuild server, string data) { // Wait! If it's a ping, it will start with <@ and end with > string newdata = data; if (data.StartsWith("<@") && data.EndsWith(">")) { newdata = data.Substring(2, data.Length - 3); } // I don't know if this method is used but it's one Discord supports so I have to support it too. if (data.StartsWith("<@!") && data.EndsWith(">")) { newdata = data.Substring(3, data.Length - 4); } if (ulong.TryParse(newdata, out ulong uuid)) { try { DiscordUser user = await XanBotCoreSystem.Client.GetUserAsync(uuid); // Catch case: Someone's username is a bunch of numbers OR they link a user ID that isn't in the server. if (user != null) { XanBotMember member = XanBotMember.GetMemberFromUser(server, user); if (member != null) { return(member); } } } catch (NotFoundException) { // The person typed in a number, it doesn't correspond to a discord GUID, so we'll catch the NotFoundException and let the code continue. } } List <XanBotMember> potentialReturns = new List <XanBotMember>(); string dataLower = data.ToLower(); // Discriminator searching: if (dataLower.Length == 5 && dataLower.First() == '#' && ushort.TryParse(dataLower.Substring(1), out ushort _)) { // This is a discriminator -- Length is 5, starts with #, and the last 4 chars are numbers. foreach (DiscordUser user in server.Members.Values) { string ud = "#" + user.Discriminator; if (dataLower == ud) { potentialReturns.Add(XanBotMember.GetMemberFromUser(server, user)); } } } if (potentialReturns.Count == 0) { // ONLY if discriminator searching found nothing will we search by display name or username. if (NeedsNewMemberCache) { LastCheckTime = DateTime.Now; Members = await server.GetAllMembersAsync(); } foreach (DiscordMember member in Members) { //foreach (DiscordMember member in server.Members.Values) { // DO NOT USE THIS. It's not fully populated in large servers. string fullName = member.Username + "#" + member.Discriminator; string nickName = member.Nickname ?? ""; fullName = fullName.ToLower(); nickName = nickName.ToLower(); if (nickName.Length >= dataLower.Length && dataLower == nickName.Substring(0, dataLower.Length)) { potentialReturns.Add(XanBotMember.GetMemberFromUser(server, member)); } else if (fullName.Length >= dataLower.Length && dataLower == fullName.Substring(0, dataLower.Length)) { potentialReturns.Add(XanBotMember.GetMemberFromUser(server, member)); } // Do NOT break if there are multiple. This is necessary for the values in a potential NonSingularResultException } } XanBotMember[] potentialReturnsArray = potentialReturns.ToArray(); if (potentialReturnsArray.Length == 0) { return(null); } else if (potentialReturnsArray.Length == 1) { return(potentialReturnsArray[0]); } else { throw new NonSingularResultException(string.Format("More than one member of the server was found with the search query `{0}`!", data), potentialReturnsArray); } }
/// <summary> /// Executes the command. This does not check if the user can run it. Check if the user is authorized before using this method. /// </summary> /// <param name="context">The <see cref="BotContext"/> this command is running in.</param> /// <param name="executingMember">The member executing this command.</param> /// <param name="originalMessage">The DiscordMessage that was responsible for invoking this command.</param> /// <param name="args">The arguments of the command split via shell32.DLL's handling system.</param> /// <param name="allArgs">Every argument passed into this command as its raw string. This is used to preserve quotes and other characters stripped by shell32.</param> public abstract Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs);
/// <summary> /// Returns true if the specified member can use this command in the specified channel. If this is the case, <paramref name="optimalTargetChannel"/> is expected to be set to null.<para/> /// If the function returns false, it expects <paramref name="optimalTargetChannel"/> to be set to a non-null value, which represents the best channel to use the command in (so if there's multiple channels, it should be the best one suited for this command) /// </summary> /// <param name="member">The member using this command.</param> /// <param name="channel">The channel they are trying to use the command in.</param> /// <returns></returns> public virtual bool CanUseCommandInThisChannel(XanBotMember member, DiscordChannel channel, out DiscordChannel optimalTargetChannel) { optimalTargetChannel = null; return(true); }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length == 0) { string text = "Commands in yellow with a `+` before them are commands you can use. Commands in red with a `-` before them are commands you cannot use. "; text += "\nSay **`{0}help command_name_here`** to get more documentation on a specific command. Say **`{0}help help`** to get information on how commands work."; text += "```diff\n"; foreach (Command cmd in CommandMarshaller.Commands) { int spaces = 34; string usagePrefix = "+ "; if (executingMember != null) { usagePrefix = cmd.CanUseCommand(executingMember).CanUse ? "+ " : "- "; } text += usagePrefix + cmd.Name; spaces -= (cmd.Name.Length + 2); for (int i = 0; i < spaces; i++) { text += " "; } text += $"Requires Permission Level {cmd.RequiredPermissionLevel} (or higher)."; text += "\n"; } if (context != null && context.Commands.Length > 0) { text += "\nCommands specific to this server:\n\n"; foreach (Command cmd in context.Commands) { int spaces = 34; string usagePrefix = "+"; if (executingMember != null) { usagePrefix = cmd.CanUseCommand(executingMember).CanUse ? "+ " : "- "; } text += usagePrefix + cmd.Name; spaces -= (cmd.Name.Length + 2); for (int i = 0; i < spaces; i++) { text += " "; } text += $"Requires Permission Level {cmd.RequiredPermissionLevel} (or higher)."; text += "\n"; } } text += "```\n"; text = string.Format(text, CommandMarshaller.CommandPrefix); await ResponseUtil.RespondToAsync(originalMessage, text); } else if (args.Length == 1) { string command = args[0]; string cmdLower = command.ToLower(); foreach (Command cmd in CommandMarshaller.Commands) { if (cmd.Name.ToLower() == cmdLower) { await ResponseUtil.RespondToAsync(originalMessage, GetFormattedCommandHelpInfo(cmd, cmd.Name)); return; } else if (cmd.AlternateNames != null) { foreach (string alt in cmd.AlternateNames) { if (alt.ToLower() == cmdLower) { await ResponseUtil.RespondToAsync(originalMessage, GetFormattedCommandHelpInfo(cmd, alt)); return; } } } } if (context.Commands.Length > 0) { foreach (Command cmd in context.Commands) { if (cmd.Name.ToLower() == cmdLower) { await ResponseUtil.RespondToAsync(originalMessage, GetFormattedCommandHelpInfo(cmd, cmd.Name)); return; } else if (cmd.AlternateNames != null) { foreach (string alt in cmd.AlternateNames) { if (alt.ToLower() == cmdLower) { await ResponseUtil.RespondToAsync(originalMessage, GetFormattedCommandHelpInfo(cmd, alt)); return; } } } } } throw new CommandException(this, "Command `" + command + "` does not exist."); } else { throw new CommandException(this, "Invalid argument count. Expected no arguments, or one argument which is the name of the command you wish to get details on."); } }
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { if (args.Length == 0) { throw new CommandException(this, "Invalid argument count. Expected at least one argument."); } else if (args.Length >= 1) { XConfiguration targetConfig = XConfiguration.GetConfigurationUtility(context); // If there is 1 or more arguments... string subCommand = args[0].ToLower(); // >> config list if (subCommand == "list") { string message = "**Configuration Values:**\n```lua\n"; string[] keys = targetConfig.Keys.ToArray(); foreach (string key in keys) { message += "[\"" + key + "\"]=" + targetConfig.GetConfigurationValue(key) + "\n"; } message += "```"; await ResponseUtil.RespondToAsync(originalMessage, message); // >> config get } else if (subCommand == "get") { if (args.Length != 2) { throw new CommandException(this, "Expected two arguments for operation \"get\" -- get <key>"); } if (args[1].Contains(' ')) { throw new CommandException(this, "Config keys cannot contain spaces."); } string value = targetConfig.GetConfigurationValue(args[1]); if (value != null) { await ResponseUtil.RespondToAsync(originalMessage, "```\n[" + args[1] + "]=" + value + "\n```"); } else { await ResponseUtil.RespondToAsync(originalMessage, "The specified key does not exist in the configuration."); } // >> config set } else if (subCommand == "set") { if (args.Length != 3) { throw new CommandException(this, "Expected two arguments for operation \"set\" -- set <key> <value>"); } if (args[1].Contains(' ')) { throw new CommandException(this, "Config keys cannot contain spaces."); } targetConfig.SetConfigurationValue(args[1], args[2]); await ResponseUtil.RespondToAsync(originalMessage, "Set [`" + args[1] + "`] to: `" + args[2] + "`"); // >> config remove } else if (subCommand == "remove") { if (args.Length != 2) { throw new CommandException(this, "Expected two arguments for operation \"remove\" -- remove <key>"); } if (args[1].Contains(' ')) { throw new CommandException(this, "Config keys cannot contain spaces."); } bool wasRemoved = targetConfig.RemoveConfigurationValue(args[1]); if (wasRemoved) { await ResponseUtil.RespondToAsync(originalMessage, $"Removed configuration entry `{args[1]}`"); } else { await ResponseUtil.RespondToAsync(originalMessage, $"Could not remove configuration entry `{args[1]}` -- it doesn't exist in the first place."); } // something else } else { throw new CommandException(this, string.Format("Invalid operation \"{0}\" (expected get, set, remove, or list)", subCommand)); } } }
/// <summary> /// Try running this passive handler. Returns true if the passive handler should intercept the message and prevent other passive handlers from picking it up. /// </summary> /// <param name="executingMember">The <see cref="XanBotMember"/> who will be executing this handler.</param> /// <param name="originalMessage">The <see cref="DiscordMessage"/> the member sent.</param> /// <returns></returns> public abstract Task <bool> RunHandlerAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage);
public override async Task ExecuteCommandAsync(BotContext context, XanBotMember executingMember, DiscordMessage originalMessage, string[] args, string allArgs) { await ResponseUtil.RespondToAsync(originalMessage, "Hello, " + executingMember.Member.Mention); }