public override async ValueTask <CheckResult> CheckAsync(DiscordGuildCommandContext context)
        {
            var guildSettingsService = context.Services.GetRequiredService <GuildSettingsService>();
            var isPermitted          = await guildSettingsService.GuildIsPermittedAsync(context.GuildId);

            return(isPermitted ? Success() : Failure("Your guild is not permitted."));
        }
        public override ValueTask <TypeParserResult <IMember?> > ParseAsync(
            Parameter parameter,
            string value,
            DiscordGuildCommandContext context)
        {
            var parsed = base.ParseAsync(parameter, value, context);

            return(!parsed.IsCompletedSuccessfully ?
                   new ValueTask <TypeParserResult <IMember?> >(TypeParserResult <IMember?> .Successful(null)) :
                   parsed);
        }
Example #3
0
 public EvalGuildGlobals(DiscordGuildCommandContext context) : base(context)
 {
     Context = context;
 }
Example #4
0
        /// <inheritdoc/>
        public override ValueTask <TypeParserResult <IRole> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            if (!context.Bot.CacheProvider.TryGetRoles(context.GuildId, out var roleCache))
            {
                throw new InvalidOperationException($"The {GetType().Name} requires the role cache.");
            }

            IRole role;

            if (Snowflake.TryParse(value, out var id) || Mention.TryParseRole(value, out id))
            {
                // The value is a mention or id.
                role = roleCache.GetValueOrDefault(id);
            }
            else
            {
                // The value is possibly a name.
                role = roleCache.Values.FirstOrDefault(x => x.Name == value);
            }

            if (role != null)
            {
                return(Success(role));
            }

            return(Failure("No role found matching the input."));
        }
Example #5
0
        /// <inheritdoc/>
        public override ValueTask <TypeParserResult <TChannel> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            if (!context.Bot.CacheProvider.TryGetChannels(context.GuildId, out var cache))
            {
                throw new InvalidOperationException($"The {GetType().Name} requires the channel cache.");
            }

            // Wraps the cache in a pattern-matching wrapper dictionary.
            var      channels = new ReadOnlyOfTypeDictionary <Snowflake, CachedGuildChannel, TChannel>(cache);
            TChannel channel;

            if (Snowflake.TryParse(value, out var id) || Mention.TryParseChannel(value, out id))
            {
                // The value is a mention or an id.
                channel = channels.GetValueOrDefault(id);
            }
            else
            {
                // The value is possibly a name.
                channel = channels.Values.FirstOrDefault(x => x.Name == value);
            }

            if (channel != null)
            {
                return(Success(channel));
            }

            return(Failure($"No {ChannelString} found matching the input."));
        }
Example #6
0
 protected override (string Name, IMember Member) GetTarget(DiscordGuildCommandContext context)
 => ("bot", context.CurrentMember);
Example #7
0
        public override async ValueTask <TypeParserResult <IUser> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            if (!Snowflake.TryParse(value, out var id) || await context.Bot.FetchUserAsync(id) is not {
            } user)
            {
                return(Failure("Please enter a valid user id."));
            }

            return(Success(user));
        }
Example #8
0
        /// <inheritdoc/>
        public override async ValueTask <TypeParserResult <IMember> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            IMember member;

            if (Snowflake.TryParse(value, out var id) || Mention.TryParseUser(value, out id))
            {
                // The value is a mention or an ID.
                // We look up the cache first.
                if (!context.Guild.Members.TryGetValue(id, out member))
                {
                    // This means it's either an invalid ID or the member isn't cached.
                    // We don't know which one it is, so we have to query the guild.
                    await using (context.BeginYield())
                    {
                        // Check if the gateway is/will be rate-limited.
                        if (context.Bot.GetShard(context.GuildId).RateLimiter.GetRemainingRequests() < 3)
                        {
                            // Use a REST call instead.
                            member = await context.Bot.FetchMemberAsync(context.GuildId, id).ConfigureAwait(false);
                        }
                        else
                        {
                            // Otherwise use gateway member chunking.
                            var members = await context.Bot.Chunker.QueryAsync(context.GuildId, new[] { id }).ConfigureAwait(false);

                            member = members.GetValueOrDefault(id);
                        }
                    }
                }
            }
            else
            {
                // The value is possibly a tag, name, or nick.
                // So let's check for a '#', indicating a tag.
                string name, discriminator;
                var    hashIndex = value.LastIndexOf('#');
                if (hashIndex != -1 && hashIndex + 5 == value.Length)
                {
                    // The value is a tag (Name#0000);
                    name          = value.Substring(0, value.Length - 5);
                    discriminator = value.Substring(hashIndex + 1);
                }
                else
                {
                    // The value is possibly a name or a nick.
                    name          = value;
                    discriminator = null;
                }

                // The predicate checks for the given tag or name/nick accordingly.
                Func <IMember, bool> predicate = discriminator != null
                    ? x => x.Name == name && x.Discriminator == discriminator
                    : x => x.Name == name || x.Nick == name;

                // We look up the cache first.
                member = context.Guild.Members.Values.FirstOrDefault(predicate);
                if (member == null)
                {
                    // This means it's either an invalid input or the member isn't cached.
                    await using (context.BeginYield())
                    {
                        // We don't know which one it is, so we have to query the guild.
                        // Check if the gateway is/will be rate-limited.
                        // TODO: swap these two around?
                        IEnumerable <IMember> members;
                        if (context.Bot.GetShard(context.GuildId).RateLimiter.GetRemainingRequests() < 3)
                        {
                            members = await context.Bot.SearchMembersAsync(context.GuildId, name);
                        }
                        else
                        {
                            members = (await context.Bot.Chunker.QueryAsync(context.GuildId, name).ConfigureAwait(false)).Values;
                        }

                        member = members.FirstOrDefault(predicate);
                    }
                }
            }

            if (member != null)
            {
                return(Success(member));
            }

            return(Failure("No member found matching the input."));
        }
Example #9
0
        /// <inheritdoc/>
        public override async ValueTask <TypeParserResult <IMember> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            if (!context.Bot.CacheProvider.TryGetMembers(context.GuildId, out var memberCache))
            {
                throw new InvalidOperationException($"The {GetType().Name} requires the member cache.");
            }

            IMember member;

            if (Snowflake.TryParse(value, out var id) || Mention.TryParseUser(value, out id))
            {
                // The value is a mention or an ID.
                // We look up the cache first.
                if (!memberCache.TryGetValue(id, out var cachedMember))
                {
                    // This means it's either an invalid ID or the member isn't cached.
                    // We don't know which one it is, so we have to query the guild.
                    await using (context.BeginYield())
                    {
                        // Check if the gateway is/will be rate-limited.
                        if (context.Bot.GetShard(context.GuildId).RateLimiter.GetRemainingRequests() < 3)
                        {
                            // Use a REST call instead.
                            member = await context.Bot.FetchMemberAsync(context.GuildId, id).ConfigureAwait(false);
                        }
                        else
                        {
                            // Otherwise use gateway member chunking.
                            var members = await context.Bot.Chunker.QueryAsync(context.GuildId, new[] { id }).ConfigureAwait(false);

                            member = members.GetValueOrDefault(id);
                        }
                    }
                }
                else
                {
                    // Have to assign the `out var cachedMember` like this.
                    member = cachedMember;
                }
            }
            else
            {
                // The value is possibly a tag, name, or nick.
                // So let's check for a '#', indicating a tag.
                string name;
                string discriminator;
                var    hashIndex = value.LastIndexOf('#');
                if (hashIndex != -1 && hashIndex + 5 == value.Length)
                {
                    // The value is a tag (Name#0000);
                    name          = value.Substring(0, value.Length - 5);
                    discriminator = value.Substring(hashIndex + 1);
                }
                else
                {
                    // The value is possibly a name or a nick.
                    name          = value;
                    discriminator = null;
                }
        /// <inheritdoc/>
        public override ValueTask <TypeParserResult <IGuildEmoji> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            if (LocalCustomEmoji.TryParse(value, out var emoji))
            {
                if (context.Guild.Emojis.TryGetValue(emoji.Id, out var guildEmoji))
                {
                    return(Success(guildEmoji));
                }

                return(Failure("The provided custom emoji is not from this guild."));
            }

            return(Failure("Invalid custom emoji."));
        }
Example #11
0
        public override ValueTask <TypeParserResult <Reminder> > ParseAsync(Parameter parameter, string value, DiscordGuildCommandContext context)
        {
            var result = context.Services.GetRequiredService <EnglishTimeParser>().Parse(value);

            if (result is not ISuccessfulTimeParsingResult <DateTime> successfulResult)
            {
                return(Failure((result as IFailedTimeParsingResult) !.ErrorReason));
            }

            var reminderValue = successfulResult.LastParsedTokenIndex == value.Length ?
                                value[..successfulResult.FirstParsedTokenIndex] :
Example #12
0
 protected override (string Name, IMember Member) GetTarget(DiscordGuildCommandContext context)
 => ("author", context.Author);