public async Task SwitchReaderAsync(IGuildUser oldReaderUser, IGuildUser newReaderUser) { Verify.IsNotNull(oldReaderUser, nameof(oldReaderUser)); Verify.IsNotNull(newReaderUser, nameof(newReaderUser)); bool switchSuccessful = false; ulong oldReaderRoleId = 0; await this.DoReadWriteActionOnCurrentTournamentAsync( async currentTournament => { // Only allow this after the tournament has started running if (!currentTournament.IsTorunamentInPlayStage()) { await this.SendChannelMessage(BotStrings.CommandOnlyUsedWhileTournamentRunning); return; } oldReaderRoleId = currentTournament.TournamentRoles.ReaderRoomRoleIds.Select(kvp => kvp.Value) .Join(oldReaderUser.RoleIds, id => id, id => id, (roomRoleId, readerRoleId) => roomRoleId) .FirstOrDefault(); if (oldReaderRoleId == default(ulong)) { await this.SendChannelMessage(BotStrings.CouldntGetRoleForTheOldReader); return; } if (!currentTournament.IsReader(oldReaderUser.Id)) { await this.SendChannelMessage(BotStrings.NotACurrentReader(oldReaderUser.Mention)); return; } else if (currentTournament.IsReader(newReaderUser.Id)) { await this.SendChannelMessage(BotStrings.IsAlreadyReader(newReaderUser.Mention)); return; } if (!currentTournament.TryRemoveReader(oldReaderUser.Id)) { await this.SendChannelMessage(BotStrings.UnknownErrorRemovingOldReader); return; } Reader newReader = new Reader() { Id = newReaderUser.Id, Name = newReaderUser.Nickname ?? newReaderUser.Username }; currentTournament.AddReaders(new Reader[] { newReader }); switchSuccessful = true; }); if (!switchSuccessful) { return; } IRole oldReaderRole = this.Context.Guild.GetRole(oldReaderRoleId); List <Task> roleChangeTasks = new List <Task> { newReaderUser.AddRoleAsync(oldReaderRole, RequestOptionsSettings.Default), oldReaderUser.RemoveRoleAsync(oldReaderRole, RequestOptionsSettings.Default) }; await Task.WhenAll(roleChangeTasks); await this.SendChannelMessage(BotStrings.ReadersSwitchedSuccessfully); }