示例#1
0
        internal async Task HandleOnReactionRemoved(
            Cacheable <IUserMessage, ulong> cachedMessage, ISocketMessageChannel messageChannel, SocketReaction reaction)
        {
            if (!cachedMessage.HasValue || reaction.UserId == this.Client.CurrentUser.Id)
            {
                // Ignore the bot's own additions.
                return;
            }

            if (!(reaction.Channel is IGuildChannel guildChannel))
            {
                // Only listen to guild reacts.
                this.Logger.Verbose("Reaction removal ignored because it wasn't on a guild channel");
                return;
            }

            if (!(reaction.User.IsSpecified && reaction.User.Value is IGuildUser guildUser))
            {
                this.Logger.Verbose("Reaction removal ignored because it wasn't by a guild user");
                return;
            }

            // Issue: when we remove a reaction, this will remove the team they were on. How would we know this, outside
            // of keeping state on this?
            // When the user chooses two emojis, and the bot removes the second one, the event handler is called. We
            // need to make sure that the user initiated this removal, which we can do by making sure that the player
            // we're removing from the set has the same team as the emoji maps to.
            // TODO: We may want to make this a dictionary of IDs to Players to make this operation efficient. We could
            // use ContainsKey to do the contains checks efficiently.
            await this.GetTournamentsManager(guildChannel.Guild).DoReadWriteActionOnCurrentTournamentForMemberAsync(
                guildUser,
                async currentTournament =>
            {
                Player player = this.GetPlayerFromReactionEventOrNull(
                    currentTournament, guildUser, cachedMessage.Id, reaction.Emote.Name, out string errorMessage);
                if (player == null)
                {
                    // User should have already received an error message from the add if it was relevant.
                    this.Logger.Verbose(
                        "Reaction addition ignored because it wasn't by a player. Message: {errorMessage}",
                        errorMessage);
                    return;
                }

                if (currentTournament.TryGetPlayerTeam(guildUser.Id, out Team storedTeam) &&
                    storedTeam == player.Team &&
                    currentTournament.TryRemovePlayer(guildUser.Id))
                {
                    this.Logger.Debug("Player {id} left team {name}", player.Id, player.Team.Name);
                    await guildUser.SendMessageAsync(
                        BotStrings.YouHaveLeftTeam(player.Team.Name), options: RequestOptionsSettings.Default);
                }
            });
        }