示例#1
0
        public override ValueTask <TypeParserResult <SocketTextChannel> > ParseAsync(
            Parameter param,
            string value,
            CommandContext context)
        {
            var ctx = context.Cast <VolteContext>();
            SocketTextChannel channel = default;

            if (ulong.TryParse(value, out var id) || MentionUtils.TryParseChannel(value, out id))
            {
                channel = ctx.Client.GetChannel(id).Cast <SocketTextChannel>();
            }

            if (channel is null)
            {
                var match = ctx.Guild.TextChannels.Where(x => x.Name.EqualsIgnoreCase(value))
                            .ToList();
                if (match.Count > 1)
                {
                    return(TypeParserResult <SocketTextChannel> .Failed(
                               "Multiple channels found. Try mentioning the channel or using its ID."));
                }
            }

            return(channel is null
                ? TypeParserResult <SocketTextChannel> .Failed("Channel not found.")
                : TypeParserResult <SocketTextChannel> .Successful(channel));
        }
示例#2
0
        public override ValueTask <TypeParserResult <DiscordColor> > ParseAsync(Parameter parameter, string value, RiasCommandContext context)
        {
            var hex = RiasUtilities.HexToInt(value);

            if (hex.HasValue)
            {
                return(TypeParserResult <DiscordColor> .Successful(new DiscordColor(hex.Value)));
            }

            var color = default(System.Drawing.Color);

            if (Enum.TryParse <System.Drawing.KnownColor>(value.Replace(" ", string.Empty), true, out var knownColor))
            {
                color = System.Drawing.Color.FromKnownColor(knownColor);
            }

            if (!color.IsEmpty)
            {
                return(TypeParserResult <DiscordColor> .Successful(new DiscordColor(color.R, color.G, color.B)));
            }

            var localization = context.Services.GetRequiredService <Localization>();

            return(TypeParserResult <DiscordColor> .Failed(localization.GetText(context.Guild?.Id, Localization.TypeParserInvalidColor)));
        }
示例#3
0
        public override async ValueTask <TypeParserResult <DiscordUser> > ParseAsync(Parameter parameter, string value, RiasCommandContext context)
        {
            var cachedMemberTypeParser = await new MemberTypeParser().ParseAsync(parameter, value, context);

            if (cachedMemberTypeParser.IsSuccessful)
            {
                return(TypeParserResult <DiscordUser> .Successful(cachedMemberTypeParser.Value));
            }

            var localization = context.Services.GetRequiredService <Localization>();

            if (ulong.TryParse(value, out var id))
            {
                try
                {
                    var user = await context.Client.GetUserAsync(id);

                    return(TypeParserResult <DiscordUser> .Successful(user));
                }
                catch
                {
                    return(TypeParserResult <DiscordUser> .Failed(localization.GetText(context.Guild?.Id, Localization.AdministrationUserNotFound)));
                }
            }

            return(TypeParserResult <DiscordUser> .Failed(localization.GetText(context.Guild?.Id, Localization.AdministrationUserNotFound)));
        }
示例#4
0
        public override ValueTask <TypeParserResult <DiscordRole> > ParseAsync(Parameter parameter, string value, RiasCommandContext context)
        {
            var localization = context.Services.GetRequiredService <Localization>();

            if (context.Guild is null)
            {
                return(TypeParserResult <DiscordRole> .Failed(localization.GetText(context.Guild?.Id, Localization.TypeParserRoleNotGuild)));
            }

            DiscordRole?role;

            if (RiasUtilities.TryParseRoleMention(value, out var roleId) || ulong.TryParse(value, out roleId))
            {
                role = context.Guild.GetRole(roleId);
                if (role != null)
                {
                    return(TypeParserResult <DiscordRole> .Successful(role));
                }

                return(TypeParserResult <DiscordRole> .Failed(localization.GetText(context.Guild?.Id, Localization.AdministrationRoleNotFound)));
            }

            role = context.Guild.Roles.FirstOrDefault(x => string.Equals(x.Value.Name, value, StringComparison.OrdinalIgnoreCase)).Value;
            if (role != null)
            {
                return(TypeParserResult <DiscordRole> .Successful(role));
            }

            return(TypeParserResult <DiscordRole> .Failed(localization.GetText(context.Guild?.Id, Localization.AdministrationRoleNotFound)));
        }
示例#5
0
        public override ValueTask <TypeParserResult <SocketRole> > ParseAsync(
            Parameter param,
            string value,
            CommandContext context)
        {
            var        ctx  = context.Cast <VolteContext>();
            SocketRole role = default;

            if (ulong.TryParse(value, out var id) || MentionUtils.TryParseRole(value, out id))
            {
                role = ctx.Guild.GetRole(id).Cast <SocketRole>();
            }

            if (role is null)
            {
                var match = ctx.Guild.Roles.Where(x => x.Name.EqualsIgnoreCase(value)).ToList();
                if (match.Count > 1)
                {
                    return(TypeParserResult <SocketRole> .Failed(
                               "Multiple roles found. Try mentioning the role or using its ID."));
                }

                role = match.FirstOrDefault().Cast <SocketRole>();
            }

            return(role is null
                ? TypeParserResult <SocketRole> .Failed($"Role `{value}` not found.")
                : TypeParserResult <SocketRole> .Successful(role));
        }
示例#6
0
        public override async ValueTask <TypeParserResult <DiscordChannel> > ParseAsync(Parameter parameter, string value, CommandContext context)
        {
            if (!(context is DiscordCommandContext ctx))
            {
                return(TypeParserResult <DiscordChannel> .Failed("Context failed to parse to DiscordCommandContext"));
            }

            var valToParse = value;

            if (valToParse.StartsWith("<#"))
            {
                valToParse = valToParse.Replace("<#", string.Empty);
            }

            if (valToParse.EndsWith(">"))
            {
                valToParse = valToParse.Replace(">", string.Empty);
            }

            if (ulong.TryParse(valToParse, out ulong res))
            {
                var chan = await ctx.Client.GetChannelAsync(res);

                if (chan is null)
                {
                    return(TypeParserResult <DiscordChannel> .Failed("Failed to get a channel."));
                }

                return(TypeParserResult <DiscordChannel> .Successful(chan));
            }
            else
            {
                return(TypeParserResult <DiscordChannel> .Failed("Failed to get a valid channel ID."));
            }
        }
示例#7
0
        public override ValueTask <TypeParserResult <SocketGuild> > ParseAsync(
            Parameter parameter,
            string value,
            CommandContext context)
        {
            var         ctx   = context.Cast <VolteContext>();
            SocketGuild guild = default;

            var guilds = ctx.Client.Guilds;

            if (ulong.TryParse(value, out var id))
            {
                guild = guilds.FirstOrDefault(x => x.Id == id);
            }

            if (guild is null)
            {
                var match = guilds.Where(x =>
                                         x.Name.EqualsIgnoreCase(value)).ToList();
                if (match.Count > 1)
                {
                    return(TypeParserResult <SocketGuild> .Failed(
                               "Multiple guilds found with that name, try using its ID."));
                }

                guild = match.FirstOrDefault();
            }

            return(guild is null
                ? TypeParserResult <SocketGuild> .Failed("Guild not found.")
                : TypeParserResult <SocketGuild> .Successful(guild));
        }
示例#8
0
        public override ValueTask <TypeParserResult <DiscordRole> > ParseAsync(Parameter parameter, string value, CommandContext context)
        {
            if (!(context is DiscordCommandContext ctx))
            {
                return(TypeParserResult <DiscordRole> .Failed("Context failed to parse to DiscordCommandContext"));
            }

            var valToParse = value;

            if (valToParse.StartsWith("<@&"))
            {
                valToParse = valToParse.Replace("<@&", string.Empty);
            }

            if (valToParse.EndsWith(">"))
            {
                valToParse = valToParse.Replace(">", string.Empty);
            }

            if (ulong.TryParse(valToParse, out ulong res))
            {
                var role = ctx.Guild.GetRole(res);
                if (role is null)
                {
                    return(TypeParserResult <DiscordRole> .Failed("Failed to get a role."));
                }

                return(TypeParserResult <DiscordRole> .Successful(role));
            }
            else
            {
                return(TypeParserResult <DiscordRole> .Failed("Failed to get a valid role ID."));
            }
        }
        public override async ValueTask <TypeParserResult <IBotUserCapsule> > ParseAsync(Parameter parameter, string value, CommandContext context)
        {
            if (context is IrcCommandContext ircCtx)
            {
                var cap = GetIrcUserCapsule(parameter, value, ircCtx);
                if (cap is not null)
                {
                    return(TypeParserResult <IBotUserCapsule> .Successful(cap));
                }
            }
            else if (context is DiscordCommandContext disCtx)
            {
                var id = GetDiscordUserId(parameter, value);

                if (id is null)
                {
                    return(TypeParserResult <IBotUserCapsule> .Failed("Failed to get a valid discord ID."));
                }

                var cap = await GetDiscordUserOrMemberCapsule(id.Value, disCtx);

                if (cap is not null)
                {
                    return(TypeParserResult <IBotUserCapsule> .Successful(cap));
                }
            }

            return(TypeParserResult <IBotUserCapsule> .Failed("Failed to get a valid user."));
        }
示例#10
0
 public override ValueTask <TypeParserResult <IEmote> > ParseAsync(
     Parameter param,
     string value,
     CommandContext context)
 => Emote.TryParse(value, out var emote)
         ? TypeParserResult <IEmote> .Successful(emote)
         : Regex.Match(value, "[^\u0000-\u007F]+", RegexOptions.IgnoreCase).Success
             ? TypeParserResult <IEmote> .Successful(new Emoji(value))
             : TypeParserResult <IEmote> .Failed("Emote not found.");
示例#11
0
        public override ValueTask <TypeParserResult <Tag> > ParseAsync(
            Parameter parameter,
            string value,
            CommandContext context)
        {
            var ctx = context.Cast <VolteContext>();
            var tag = ctx.GuildData.Extras.Tags.FirstOrDefault(x => x.Name.EqualsIgnoreCase(value));

            return(tag is null
                ? TypeParserResult <Tag> .Failed($"The tag **{value}** doesn't exist in this guild. " +
                                                 $"Try using the `{ctx.GuildData.Configuration.CommandPrefix}tags` command to see all tags in this guild.")
                : TypeParserResult <Tag> .Successful(tag));
        }
示例#12
0
        public override ValueTask <TypeParserResult <TimeSpan> > ParseAsync(Parameter parameter, string value, RiasCommandContext context)
        {
            var timespan = RiasUtilities.ConvertToTimeSpan(value);

            if (timespan.HasValue)
            {
                return(TypeParserResult <TimeSpan> .Successful(timespan.Value));
            }

            var localization = context.Services.GetRequiredService <Localization>();

            return(TypeParserResult <TimeSpan> .Failed(localization.GetText(context.Guild?.Id, Localization.TypeParserTimeSpanUnsuccessful)));
        }
示例#13
0
        public override ValueTask <TypeParserResult <bool> > ParseAsync(
            Parameter param,
            string value,
            CommandContext context)
        {
            if (TrueValues.ContainsIgnoreCase(value))
            {
                return(TypeParserResult <bool> .Successful(true));
            }

            if (FalseValues.ContainsIgnoreCase(value))
            {
                return(TypeParserResult <bool> .Successful(false));
            }

            return(bool.TryParse(value, out var result)
                ? TypeParserResult <bool> .Successful(result)
                : TypeParserResult <bool> .Failed($"Failed to parse a {typeof(bool)} (true/false) value. Try using true or false."));
        }
示例#14
0
        public override async ValueTask <TypeParserResult <RestUser> > ParseAsync(
            Parameter parameter,
            string value,
            CommandContext context)
        {
            var ctx = context.Cast <VolteContext>();

            RestUser user = default;

            if (ulong.TryParse(value, out var id) || MentionUtils.TryParseUser(value, out id))
            {
                user = await ctx.Client.Shards.First().Rest.GetUserAsync(id);
            }



            return(user is null
                ? TypeParserResult <RestUser> .Failed("User not found.")
                : TypeParserResult <RestUser> .Successful(user));
        }
示例#15
0
        public override ValueTask <TypeParserResult <SocketGuildUser> > ParseAsync(
            Parameter param,
            string value,
            CommandContext context)
        {
            var ctx   = context.Cast <VolteContext>();
            var users = ctx.Guild.Users.ToList();

            SocketGuildUser user = default;

            if (ulong.TryParse(value, out var id) || MentionUtils.TryParseUser(value, out id))
            {
                user = users.FirstOrDefault(x => x.Id == id);
            }

            if (user is null)
            {
                user = users.FirstOrDefault(x => x.ToString().EqualsIgnoreCase(value));
            }

            if (user is null)
            {
                var match = users.Where(x =>
                                        x.Username.EqualsIgnoreCase(value) ||
                                        x.Nickname.EqualsIgnoreCase(value)).ToList();
                if (match.Count > 1)
                {
                    return(TypeParserResult <SocketGuildUser> .Failed(
                               "Multiple users found, try mentioning the user or using their ID."));
                }

                user = match.FirstOrDefault();
            }

            return(user is null
                ? TypeParserResult <SocketGuildUser> .Failed("User not found.")
                : TypeParserResult <SocketGuildUser> .Successful(user));
        }
示例#16
0
        public override async ValueTask <TypeParserResult <DiscordMember> > ParseAsync(Parameter parameter, string value, CommandContext context)
        {
            if (context is DiscordCommandContext ctx)
            {
                var id = GetDiscordUserId(parameter, value);

                if (id is null)
                {
                    return(TypeParserResult <DiscordMember> .Failed("Failed to parse a valid ID."));
                }

                var user = await GetDiscordMember(id.Value, ctx);

                if (user is null)
                {
                    return(TypeParserResult <DiscordMember> .Failed($"Failed to get a valid DiscordMember from {id.Value}."));
                }

                return(TypeParserResult <DiscordMember> .Successful(user));
            }

            return(TypeParserResult <DiscordMember> .Failed("Can't get a Discord member from a non Discord client."));
        }
示例#17
0
        public override async ValueTask <TypeParserResult <DiscordMember> > ParseAsync(Parameter parameter, string value, RiasCommandContext context)
        {
            var localization = context.Services.GetRequiredService <Localization>();

            if (context.Guild is null)
            {
                return(TypeParserResult <DiscordMember> .Failed(localization.GetText(context.Guild?.Id, Localization.TypeParserMemberNotGuild)));
            }

            var riasBot = context.Services.GetRequiredService <RiasBot>();

            if (!riasBot.ChunkedGuilds.Contains(context.Guild.Id))
            {
                var botService = context.Services.GetRequiredService <BotService>();
                var tcs        = new TaskCompletionSource();
                botService.GuildsTcs[context.Guild.Id] = tcs;

                riasBot.ChunkedGuilds.Add(context.Guild.Id);
                await context.Guild.RequestMembersAsync();

                Log.Debug("Members requested for {GuildName} ({GuildId})", context.Guild.Name, context.Guild.Id);

                var delayTimeout = context.Guild.MemberCount switch
                {
示例#18
0
        public override ValueTask <TypeParserResult <DiscordChannel> > ParseAsync(Parameter parameter, string value, RiasCommandContext context)
        {
            var localization = context.Services.GetRequiredService <Localization>();

            if (context.Guild is null)
            {
                return(TypeParserResult <DiscordChannel> .Failed(localization.GetText(context.Guild?.Id, Localization.TypeParserChannelNotGuild)));
            }

            var channelType = ChannelType.Unknown;
            HashSet <ChannelType>?ignoreChannelTypes = null;

            foreach (var attribute in parameter.Attributes)
            {
                switch (attribute)
                {
                case CategoryChannelAttribute:
                    channelType = ChannelType.Category;
                    break;

                case TextChannelAttribute:
                    channelType = ChannelType.Text;
                    break;

                case VoiceChannelAttribute:
                    channelType = ChannelType.Voice;
                    break;

                case IgnoreChannelTypesAttribute ignoreChannelTypeAttribute:
                    ignoreChannelTypes = ignoreChannelTypeAttribute.ChannelTypes;
                    break;
                }
            }

            if (channelType is not ChannelType.Unknown && ignoreChannelTypes is not null && ignoreChannelTypes.Contains(channelType))
            {
                throw new ArgumentException("The required channel type and the ignored channel type cannot be the same");
            }

            DiscordChannel?channel;

            if (RiasUtilities.TryParseChannelMention(value, out var channelId) || ulong.TryParse(value, out channelId))
            {
                channel = context.Guild.GetChannel(channelId);
                if (channel is not null)
                {
                    var allowChannel = channelType switch
                    {
                        ChannelType.Text => channel.Type is ChannelType.Text or ChannelType.News or ChannelType.Store,
                        ChannelType.Voice => channel.Type is ChannelType.Voice or ChannelType.Stage,
                        _ => channel.Type == channelType || channelType is ChannelType.Unknown
                    };

                    if (allowChannel)
                    {
                        return(ignoreChannelTypes is not null && ignoreChannelTypes.Contains(channel.Type)
                            ? TypeParserResult <DiscordChannel> .Failed(localization.GetText(context.Guild.Id, Localization.TypeParserChannelNotAllowed(channel.Type.ToString().ToLower())))
                            : TypeParserResult <DiscordChannel> .Successful(channel));
                    }
                }
            }
            else
            {
                channel = channelType switch
                {
                    ChannelType.Category => context.Guild.GetCategoryChannel(value),
                    ChannelType.Text => context.Guild.GetTextChannel(value),
                    ChannelType.Voice => context.Guild.GetVoiceChannel(value),
                    ChannelType.Unknown => ignoreChannelTypes is null
                        ? context.Guild.Channels
                    .OrderBy(c => c.Value.Position)
                    .FirstOrDefault(x => string.Equals(x.Value.Name, value, StringComparison.OrdinalIgnoreCase))
                    .Value
                        : context.Guild.Channels
                    .Where(c => !ignoreChannelTypes.Contains(c.Value.Type))
                    .OrderBy(c => c.Value.Position)
                    .FirstOrDefault(x => string.Equals(x.Value.Name, value, StringComparison.OrdinalIgnoreCase))
                    .Value
                };

                if (channel != null)
                {
                    return(TypeParserResult <DiscordChannel> .Successful(channel));
                }
            }

            return(channelType switch
            {
                ChannelType.Category => TypeParserResult <DiscordChannel> .Failed(localization.GetText(context.Guild.Id, Localization.AdministrationCategoryChannelNotFound)),
                ChannelType.Text => TypeParserResult <DiscordChannel> .Failed(localization.GetText(context.Guild.Id, Localization.AdministrationTextChannelNotFound)),
                ChannelType.Voice => TypeParserResult <DiscordChannel> .Failed(localization.GetText(context.Guild.Id, Localization.AdministrationVoiceChannelNotFound)),
                ChannelType.Unknown => TypeParserResult <DiscordChannel> .Failed(localization.GetText(context.Guild.Id, Localization.AdministrationChannelNotFound))
            });