コード例 #1
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))
            });