Exemple #1
0
        internal static ModuleInfo Create(Type type)
        {
            var module = type.GetTypeInfo();

            var moduleAttribute = module.GetCustomAttribute <ModuleAttribute>();

            if (moduleAttribute == null)
            {
                throw new ArgumentException($"Type {type} is not a module.");
            }

            // Command attributes
            var commands = new List <CommandInfo>();

            foreach (var method in module.GetMethods())
            {
                var commandAttribute = method.GetCustomAttribute <CommandAttribute>();
                if (commandAttribute == null)
                {
                    continue;
                }

                // Required
                var handler      = BuildCommandHandler(type, method);
                var primaryUsage = new CommandInfo.Usage(commandAttribute.InvokeString, commandAttribute.Verbs);
                var description  = commandAttribute.Description;
                var flags        = commandAttribute.Flags;

                // Optional
                List <ParameterInfo> parameters;
                if (method.GetCustomAttribute <IgnoreParametersAttribute>() != null)
                {
                    parameters = new List <ParameterInfo>()
                    {
                        ParameterInfo.AlwaysMatching
                    }
                }
                ;
                else
                {
                    parameters = method.GetCustomAttributes <ParameterAttribute>().Select(x => x.Registration).ToList();
                }

                var userPermissions = new HashSet <GuildPermission>(method.GetCustomAttribute <PermissionsAttribute>()?.RequiredPermissions ?? Enumerable.Empty <GuildPermission>());
                var botPermissions  = new HashSet <GuildPermission>(method.GetCustomAttribute <BotPermissionsAttribute>()?.RequiredPermissions ?? Enumerable.Empty <GuildPermission>());

                var examples = method.GetCustomAttributes <ExampleAttribute>().Select(x => x.Example).ToList();
                var comment  = method.GetCustomAttribute <CommentAttribute>()?.Comment;
                var aliases  = method.GetCustomAttributes <AliasAttribute>().Select(x => new CommandInfo.Usage(x.InvokeString, x.Verbs, x.Hidden)).ToList();

                commands.Add(new CommandInfo(type, handler, primaryUsage, aliases, userPermissions, botPermissions, parameters, description, examples, flags, comment));
            }

            return(new ModuleInfo(type, moduleAttribute.Name, moduleAttribute.Description, moduleAttribute.Hidden, commands));
        }
 public SuccessCommandParseResult(
     string invoker,
     IReadOnlyCollection <string> verbs,
     string body,
     IReadOnlyCollection <ParameterToken> tokens,
     CommandInfo registration,
     CommandInfo.Usage usage,
     string prefix,
     IUserMessage message)
     : base(CommandParseResultType.Success)
 {
     Invoker      = invoker;
     Verbs        = verbs;
     Body         = body;
     Tokens       = tokens;
     Registration = registration;
     Usage        = usage;
     Prefix       = prefix;
     Message      = message;
 }
Exemple #3
0
        internal static ILogger WithCommandScope(this ILogger logger, IMessage message, Guid commandId, CommandInfo commandInfo, CommandInfo.Usage commandUsage)
        {
            var correlationIds = new Dictionary <string, object>();

            correlationIds.Add(LogFields.CommandId, commandId);
            correlationIds.Add(LogFields.CommandPrimaryUsage, commandInfo.PrimaryUsage.InvokeUsage);
            correlationIds.Add(LogFields.CommandInvokeUsage, commandUsage.InvokeUsage);
            correlationIds.Add(LogFields.CommandModuleType, commandInfo.ModuleType.Name);

            FillMessage(correlationIds, message);
            FillUser(correlationIds, message.Author);
            FillChannel(correlationIds, message.Channel);

            if (message.Channel is IGuildChannel guildChannel)
            {
                FillGuild(correlationIds, guildChannel.Guild);
            }

            return(logger.WithScope(correlationIds));
        }
Exemple #4
0
        public async Task <CommandParseResult> Parse(IUserMessage message, CommandInfo registration, CommandInfo.Usage usage, string prefix)
        {
            // Prefix
            var content = message.Content;

            if (!content.StartsWith(prefix))
            {
                return(new CommandParseResult(CommandParseResultType.InvalidPrefix));
            }

            // Invoker
            var invoker = ParseInvoker(content, prefix);

            if (string.IsNullOrEmpty(invoker) || string.Compare(invoker, usage.InvokeString, true) != 0)
            {
                return(new CommandParseResult(CommandParseResultType.InvalidInvoker));
            }

            // Verbs
            var verbs = new List <string>();
            var split = content.Split(new char[0], usage.Verbs.Count + 2 /* (invoker and body) */, StringSplitOptions.RemoveEmptyEntries);

            if (usage.HasVerbs)
            {
                if (split.Length < usage.Verbs.Count + 1)
                {
                    return(new CommandParseResult(CommandParseResultType.MissingVerbs));
                }

                for (int i = 0; i < usage.Verbs.Count; ++i)
                {
                    if (string.Compare(split[i + 1], usage.Verbs[i], true) != 0)
                    {
                        return(new CommandParseResult(CommandParseResultType.InvalidVerb));
                    }

                    verbs.Add(split[i + 1]);
                }
            }

            var body = split.ElementAtOrDefault(usage.Verbs.Count + 1 /* invoker */) ?? string.Empty;

            // Check for parser limitations
            if (registration.Parameters.SkipLast().Any(x => x.Flags.HasFlag(ParameterFlags.Repeatable)))
            {
                throw new InvalidOperationException($"Command \"{registration.PrimaryUsage.InvokeUsage}\" cannot be parsed. Only the last parameter in a command can be repeatable.");
            }

            var guild          = (SocketGuild)(message.Channel as IGuildChannel)?.Guild;
            var possibleTokens = body.Tokenize(TextQualifiers.ToArray()).Select(x => new ParameterToken(x, guild, _userFetcher));
            var usedTokens     = new List <ParameterToken>();
            var paramsResult   = await ParseParameters(body, possibleTokens, registration.Parameters, usedTokens);

            if (paramsResult.Type != CommandParseResultType.Success)
            {
                return(paramsResult);
            }

            return(new SuccessCommandParseResult(invoker, verbs, body, usedTokens, registration, usage, prefix, message));
        }