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; }
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)); }
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)); }