void IService.Install(DiscordClient client) { Client = client; if (Config.HelpMode != HelpMode.Disabled) { CreateCommand("help") .Parameter("command", ParameterType.Multiple) .Hide() .Description("Returns information about commands.") .Do(async e => { Channel replyChannel = Config.HelpMode == HelpMode.Public ? e.Channel : await e.User.CreatePMChannel().ConfigureAwait(false); if (e.Args.Length > 0) //Show command help { var map = _map.GetItem(string.Join(" ", e.Args)); if (map != null) { await ShowCommandHelp(map, e.User, e.Channel, replyChannel).ConfigureAwait(false); } else { await replyChannel.SendMessage("Unable to display help: Unknown command.").ConfigureAwait(false); } } else //Show general help { await ShowGeneralHelp(e.User, e.Channel, replyChannel).ConfigureAwait(false); } }); } client.MessageReceived += async(s, e) => { if (_allCommands.Count == 0) { return; } if (Config.IsSelfBot) { if (e.Message.User == null || e.Message.User.Id != Client.CurrentUser.Id) { return; // Will only listen to Self } } else if (e.Message.User == null || e.Message.User.Id == Client.CurrentUser.Id) { return; // Normal expected behavior for bots } string msg = e.Message.RawText; if (msg.Length == 0) { return; } string cmdMsg = null; //Check for command char if (Config.PrefixChar.HasValue) { if (msg[0] == Config.PrefixChar.Value) { cmdMsg = msg.Substring(1); } } //Check for mention if (cmdMsg == null && Config.AllowMentionPrefix) { string mention = client.CurrentUser.Mention; if (msg.StartsWith(mention) && msg.Length > mention.Length) { cmdMsg = msg.Substring(mention.Length + 1); } else { mention = $"@{client.CurrentUser.Name}"; if (msg.StartsWith(mention) && msg.Length > mention.Length) { cmdMsg = msg.Substring(mention.Length + 1); } } string mention2 = client.CurrentUser.NicknameMention; if (mention2 != null) { if (msg.StartsWith(mention2) && msg.Length > mention2.Length) { cmdMsg = msg.Substring(mention2.Length + 1); } else { mention2 = $"@{client.CurrentUser.Name}"; if (msg.StartsWith(mention2) && msg.Length > mention2.Length) { cmdMsg = msg.Substring(mention2.Length + 1); } } } } //Check using custom activator if (cmdMsg == null && Config.CustomPrefixHandler != null) { int index = Config.CustomPrefixHandler(e.Message); if (index >= 0) { cmdMsg = msg.Substring(index); } } if (cmdMsg == null) { return; } //Parse command IEnumerable <Command> commands; int argPos; CommandParser.ParseCommand(cmdMsg, _map, out commands, out argPos); if (commands == null) { CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null); OnCommandError(CommandErrorType.UnknownCommand, errorArgs); return; } else { foreach (var command in commands) { //Parse arguments string[] args; var error = CommandParser.ParseArgs(cmdMsg, argPos, command, out args); if (error != null) { if (error == CommandErrorType.BadArgCount) { continue; } else { var errorArgs = new CommandEventArgs(e.Message, command, null); OnCommandError(error.Value, errorArgs); return; } } var eventArgs = new CommandEventArgs(e.Message, command, args); // Check permissions string errorText; if (!command.CanRun(eventArgs.User, eventArgs.Channel, out errorText)) { OnCommandError(CommandErrorType.BadPermissions, eventArgs, errorText != null ? new Exception(errorText) : null); return; } // Run the command try { OnCommand(eventArgs); await command.Run(eventArgs).ConfigureAwait(false); } catch (Exception ex) { OnCommandError(CommandErrorType.Exception, eventArgs, ex); } return; } var errorArgs2 = new CommandEventArgs(e.Message, null, null); OnCommandError(CommandErrorType.BadArgCount, errorArgs2); } }; }
public CommandsPlugin(DiscordClient client, Func <User, int> getPermissions = null) { _client = client; _getPermissions = getPermissions; _commands = new List <Command>(); CommandChar = '/'; UseCommandChar = false; RequireCommandCharInPublic = true; RequireCommandCharInPrivate = true; client.MessageReceived += async(s, e) => { //If commands aren't being used, don't bother processing them if (_commands.Count == 0) { return; } //Ignore messages from ourselves if (e.Message.User == client.CurrentUser) { return; } //Check for the command character string msg = e.Message.Text; if (UseCommandChar) { if (msg.Length == 0) { return; } bool isPrivate = e.Message.Channel.IsPrivate; bool hasCommandChar = msg[0] == CommandChar; if (hasCommandChar) { msg = msg.Substring(1); } if (!isPrivate && RequireCommandCharInPublic && !hasCommandChar) { return; } if (isPrivate && RequireCommandCharInPrivate && !hasCommandChar) { return; } } CommandPart[] args; if (!CommandParser.ParseArgs(msg, out args)) { return; } for (int i = 0; i < _commands.Count; i++) { Command cmd = _commands[i]; //Check Command Parts if (args.Length < cmd.Parts.Length) { continue; } bool isValid = true; for (int j = 0; j < cmd.Parts.Length; j++) { if (!string.Equals(args[j].Value, cmd.Parts[j], StringComparison.OrdinalIgnoreCase)) { isValid = false; break; } } if (!isValid) { continue; } //Check Arg Count int argCount = args.Length - cmd.Parts.Length; if (argCount < cmd.MinArgs || argCount > cmd.MaxArgs) { continue; } //Clean Args string[] newArgs = new string[argCount]; for (int j = 0; j < newArgs.Length; j++) { newArgs[j] = args[j + cmd.Parts.Length].Value; } //Get ArgText string argText; if (argCount == 0) { argText = ""; } else { argText = msg.Substring(args[cmd.Parts.Length].Index); } //Check Permissions int permissions = _getPermissions != null?_getPermissions(e.Message.User) : 0; var eventArgs = new CommandEventArgs(e.Message, cmd, msg, argText, permissions, newArgs); if (permissions < cmd.MinPerms) { RaiseCommandError(eventArgs, new PermissionException()); return; } //Run Command RaiseRanCommand(eventArgs); try { var task = cmd.Handler(eventArgs); if (task != null) { await task.ConfigureAwait(false); } } catch (Exception ex) { RaiseCommandError(eventArgs, ex); } break; } }; }