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); } }); }