예제 #1
0
        void IService.Install(DiscordClient client)
        {
            _client = client;
            _config.Lock();

            if (_config.HelpMode != HelpMode.Disable)
            {
                CreateCommand("help")
                    .Parameter("command", ParameterType.Multiple)
                    .Hide()
                    .Description("Returns information about commands.")
                    .Do((Func<CommandEventArgs, Task>)(async e =>
                    {
                        Channel replyChannel = _config.HelpMode == HelpMode.Public ? e.Channel : await client.CreatePMChannel(e.User);
                        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);
                            else
                                await client.SendMessage(replyChannel, "Unable to display help: Unknown command.");
                        }
                        else //Show general help
                            
                            await ShowGeneralHelp(e.User, e.Channel, replyChannel);
                    }));
            }

            client.MessageReceived += async (s, e) =>
            {
                if (_allCommands.Count == 0)  return;
                if (e.Message.IsAuthor) return;

                string msg = e.Message.Text;
                if (msg.Length == 0) return;

                // Check ignored before doing work
                if (_getIgnoredChannelFlag != null ? _getIgnoredChannelFlag(e.Message.Channel, e.User) : false)
                    return;

                //Check for command char if one is provided
                var chars = _config.CommandChars;
                if (chars.Length > 0)
                {
                    bool hasCommandChar = chars.Contains(msg[0]);
                    if (!hasCommandChar && (e.Message.Channel.IsPrivate ? _config.RequireCommandCharInPrivate : _config.RequireCommandCharInPublic))
                    {
                        if (_config.MentionCommandChar >= 1 && e.Message.IsMentioningMe)
                        {
                            // It's lame we have to do this, but our User isn't exposed by Discord.Net, so we don't know our name
                            User nekouser = client.GetUser(e.Server, client.CurrentUserId);
                            string neko = '@'+nekouser.Name;
                            if (neko.Length+2 > msg.Length || (e.Message.MentionedRoles.Contains(e.Server.EveryoneRole) && e.Message.MentionedUsers.Where(u => u == nekouser).Count() == 0))
                            {
                                NonCommands(e);
                                return;
                            }
                            if (msg.StartsWith(neko))
                                msg = msg.Substring(neko.Length+1);
                            else
                            {
                                int index = _config.MentionCommandChar > 1 ? msg.LastIndexOf(neko) : -1;
                                if (index == -1)
                                {
                                    NonCommands(e);
                                    return;
                                }
                                msg = msg.Substring(0, index-1);
                            }
                            // Ideally, don't let the command know that we were mentioned, if this is the only mention
                            /*if (msg.IndexOf(neko) != -1)
                            {
                                e.Message.MentionedUsers = e.Message.MentionedUsers.Where(u => u == nekouser);
                                e.Message.IsMentioningMe = false;
                            }*/
                        }
                        else
                        {
                            NonCommands(e);
                            return;
                        }
                    }
                    else if (hasCommandChar)
                        msg = msg.Substring(1);
                }

                //Parse command
                IEnumerable<Command> commands;
                int argPos;
                CommandParser.ParseCommand(msg, _map, out commands, out argPos);                
                if (commands == null)
                {
                    CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null);
                    RaiseCommandError(CommandErrorType.UnknownCommand, errorArgs);
                    NonCommands(e);
                    return;
                }
                else
                {
                    foreach (var command in commands)
                    {
                        //Parse arguments
                        string[] args;
                        var error = CommandParser.ParseArgs(msg, argPos, command, out args);
                        if (error != null)
                        {
                            if (error == CommandErrorType.BadArgCount)
                                continue;
                            else
                            {
                                var errorArgs = new CommandEventArgs(e.Message, command, null);
                                RaiseCommandError(error.Value, errorArgs, new Exception("Error parsing args"));
                                return;
                            }
                        }

                        var eventArgs = new CommandEventArgs(e.Message, command, args);

                        // Check permissions
                        string errorText;
                        if (!command.CanRun(eventArgs.User, eventArgs.Channel, out errorText))
                        {
                            RaiseCommandError(CommandErrorType.BadPermissions, eventArgs, new Exception(errorText ?? DefaultPermissionError));
                            return;
                        }
                        // Check flags
                        bool nsfwAllowed = _getNsfwFlag != null ? _getNsfwFlag(e.Message.Channel) : false;
                        if (!nsfwAllowed && !e.Channel.IsPrivate && command.NsfwFlag)
                        {
                            RaiseCommandError(CommandErrorType.BadPermissions, eventArgs, new NsfwFlagException());
                            return;
                        }
                        bool isInMusicChannel = _getMusicFlag != null ? _getMusicFlag(e.Message.User) : false;
                        if (command.MusicFlag && !isInMusicChannel)
                        {
                            RaiseCommandError(CommandErrorType.BadPermissions, eventArgs, new MusicFlagException());
                            return;
                        }

                        // Run the command
                        try
                        {
                            RaiseRanCommand(eventArgs);
                            await command.Run(eventArgs).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            RaiseCommandError(CommandErrorType.Exception, eventArgs, ex);
                        }
                        return;
                    }
                    var errorArgs2 = new CommandEventArgs(e.Message, null, null);
                    RaiseCommandError(CommandErrorType.BadArgCount, errorArgs2);
                }
            };
        }