Discord-Net-Labs / Discord.Net-Labs

An experimental fork of Discord.Net that implements the newest discord features for testing and development to eventually get merged into Discord.Net
https://labs.discordnet.dev
MIT License
156 stars 41 forks source link

[Bug]: Can't detect switch of User.IsPending on GuildMemberUpdated event #409

Closed Floowey closed 2 years ago

Floowey commented 2 years ago

Check The Docs

Verify Issue Source

Check your intents

Description

private async Task Client_GuildMemberUpdated(Cacheable<SocketGuildUser, ulong> before, SocketGuildUser user)
        {
            var guild = GuildSettings.GetGuildSettings(user.Guild);
            var userBefore = before.Value;

            Console.WriteLine($"User Updated: before:isPending={userBefore.IsPending.GetValueOrDefault()} after:isPending={user.IsPending.GetValueOrDefault()}");
            if (userBefore.IsPending.GetValueOrDefault() && !user.IsPending.GetValueOrDefault())
                Console.WriteLine($"{user.Username} joined");
}

I'm using the above code on a community server to check whether a joined user got past the member screening. (In place of the Writeline I send a welcome message). However, the if-statement is never entered, as in no moment that the event is called the isPending is not the same. When the user joins, the event is called and it is true for both userBefore and user, after accepting the rules its is false for both variables - no inbetween.

(Maybe it is related, but not the main issue: The following statement always triggers if the user is a booster. userBefore seems to never have the PremiumSince value set.)

            if (userBefore.PremiumSince.HasValue != user.PremiumSince.HasValue)

Both pieces of code have worked on previous versions, but I can't pinpoint on which. I'm guessing one of the 3.4 versions

Version

3.6.1

Working Version

3.4.9

Logs

User Joined: isPending=true User Updated: before: isPending=true after:isPending:true User Updated: before: isPending=false after:isPending:false (Note: after confirming rules)

Sample

No response

quinchs commented 2 years ago

The issue boils down to a bad cacheable type:

user = guild.AddOrUpdateUser(data);
var cacheableBefore = new Cacheable<SocketGuildUser, ulong>(user, user.Id, true, () => null);
await TimedInvokeAsync(_guildMemberUpdatedEvent, nameof(GuildMemberUpdated), cacheableBefore, user).ConfigureAwait(false);

Both the before and after are using the same value, which is incorrect. I'll fix this