public async Task <ITextChannel> CreateChannelsForFinals( ISelfUser botUser, ITournamentState state, Game finalsGame, int finalsRoundNumber, int roomIndex) { Verify.IsNotNull(this.Guild, "guild"); Verify.IsNotNull(state, nameof(state)); Verify.IsNotNull(finalsGame, nameof(finalsGame)); TournamentRoles roles = this.GetTournamentRoles(state); ICategoryChannel finalsCategoryChannel = await this.Guild.CreateCategoryAsync("Finals"); ITextChannel channel = await this.CreateTextChannelAsync( botUser, finalsCategoryChannel, finalsGame, roles, finalsRoundNumber, roomIndex); state.ChannelIds = state.ChannelIds .Concat(new ulong[] { channel.Id }) .Concat(new ulong[] { finalsCategoryChannel.Id }); return(channel); }
private async Task CreateArtifactsAsync(ITournamentState state) { // GetAllMembersAsync may contain the same member multiple times, which causes ToDictionary to throw. Add // members manually to a dictionary instead. IReadOnlyCollection <IGuildUser> allMembers = await this.Context.Guild.GetUsersAsync(); IDictionary <ulong, IGuildUser> members = new Dictionary <ulong, IGuildUser>(); foreach (IGuildUser member in allMembers) { members[member.Id] = member; } IRole directorRole = await this.AssignDirectorRoleAsync(state, members); Dictionary <Reader, IRole> roomReaderRoles = await this.AssignRoomReaderRolesAsync(state, members); Dictionary <Team, IRole> teamRoles = await this.AssignPlayerRolesAsync(state, members); TournamentRoles roles = new TournamentRoles() { DirectorRole = directorRole, RoomReaderRoles = roomReaderRoles, TeamRoles = teamRoles }; state.TournamentRoles = roles.ToIds(); await this.ChannelManager.CreateChannelsForPrelims(this.Context.Client.CurrentUser, state, roles); }
public async Task CreateChannelsForRebracket( ISelfUser botUser, ITournamentState state, IEnumerable <Round> rounds, int startingRoundNumber) { Verify.IsNotNull(this.Guild, "guild"); Verify.IsNotNull(state, nameof(state)); Verify.IsNotNull(rounds, nameof(rounds)); TournamentRoles roles = this.GetTournamentRoles(state); ITextChannel[] textChannels = await this.CreateTextChannelsForRounds( botUser, rounds, roles, startingRoundNumber); IEnumerable <ulong> textCategoryChannelIds = GetCategoryChannelIds(textChannels); state.ChannelIds = state.ChannelIds .Concat(textChannels.Select(channel => channel.Id)) .Concat(textCategoryChannelIds); }
private async Task <ITextChannel[]> CreateTextChannelsForRounds( ISelfUser botUser, IEnumerable <Round> rounds, TournamentRoles roles, int startingRoundNumber) { Verify.IsNotNull(this.Guild, "guild"); Verify.IsNotNull(rounds, nameof(rounds)); Verify.IsNotNull(roles, nameof(roles)); List <Task <ITextChannel> > createTextChannelsTasks = new List <Task <ITextChannel> >(); List <ulong> textCategoryChannelIds = new List <ulong>(); int roundNumber = startingRoundNumber; foreach (Round round in rounds) { int roomNumber = 0; ICategoryChannel roundCategoryChannel = await this.Guild.CreateCategoryAsync( $"Round {roundNumber}", options : RequestOptionsSettings.Default); textCategoryChannelIds.Add(roundCategoryChannel.Id); foreach (Game game in round.Games) { createTextChannelsTasks.Add(this.CreateTextChannelAsync( botUser, roundCategoryChannel, game, roles, roundNumber, roomNumber)); roomNumber++; } roundNumber++; } ITextChannel[] textChannels = await Task.WhenAll(createTextChannelsTasks); return(textChannels); }
public async Task CreateChannelsForPrelims(ISelfUser botUser, ITournamentState state, TournamentRoles roles) { Verify.IsNotNull(this.Guild, "guild"); Verify.IsNotNull(state, nameof(state)); Verify.IsNotNull(roles, nameof(roles)); List <Task <IVoiceChannel> > createVoiceChannelsTasks = new List <Task <IVoiceChannel> >(); // We only need to go through the games for the first round to get all of the readers. Round firstRound = state.Schedule.Rounds.First(); Debug.Assert(firstRound.Games.Select(game => game.Reader.Name).Count() == firstRound.Games.Select(game => game.Reader.Name).Distinct().Count(), "All reader names should be unique."); ICategoryChannel voiceCategoryChannel = await this.Guild.CreateCategoryAsync( "Readers", options : RequestOptionsSettings.Default); foreach (Game game in firstRound.Games) { createVoiceChannelsTasks.Add( this.CreateVoiceChannelAsync(voiceCategoryChannel, game.Reader)); } IVoiceChannel[] voiceChannels = await Task.WhenAll(createVoiceChannelsTasks); // Create the text channels const int startingRoundNumber = 1; ITextChannel[] textChannels = await this.CreateTextChannelsForRounds( botUser, state.Schedule.Rounds, roles, startingRoundNumber); IEnumerable <ulong> textCategoryChannelIds = GetCategoryChannelIds(textChannels); state.ChannelIds = voiceChannels.Select(channel => channel.Id) .Concat(textChannels.Select(channel => channel.Id)) .Concat(new ulong[] { voiceCategoryChannel.Id }) .Concat(textCategoryChannelIds) .ToArray(); }
private async Task <ITextChannel> CreateTextChannelAsync( ISelfUser botUser, ICategoryChannel parent, Game game, TournamentRoles roles, int roundNumber, int roomNumber) { Verify.IsNotNull(this.Guild, "guild"); Verify.IsNotNull(parent, nameof(parent)); Verify.IsNotNull(game, nameof(game)); Verify.IsNotNull(roles, nameof(roles)); // The room and role names will be the same. this.Logger.Debug("Creating text channel for room {0} in round {1}", roomNumber, roundNumber); string name = GetTextRoomName(game.Reader, roundNumber); ITextChannel channel = await this.Guild.CreateTextChannelAsync( name, channelProps => { channelProps.CategoryId = parent.Id; }, RequestOptionsSettings.Default); this.Logger.Debug("Text channel for room {0} in round {1} created", roomNumber, roundNumber); // We need to add the bot's permissions first before we disable permissions for everyone. await channel.AddPermissionOverwriteAsync( botUser, PrivilegedOverwritePermissions, RequestOptionsSettings.Default); this.Logger.Debug("Adding permissions to text channel for room {0} in round {1}", roomNumber, roundNumber); await channel.AddPermissionOverwriteAsync( this.Guild.EveryoneRole, EveryonePermissions, RequestOptionsSettings.Default); await channel.AddPermissionOverwriteAsync( roles.DirectorRole, PrivilegedOverwritePermissions, RequestOptionsSettings.Default); if (roles.RoomReaderRoles.TryGetValue(game.Reader, out IRole readerRole)) { await channel.AddPermissionOverwriteAsync( readerRole, PrivilegedOverwritePermissions, RequestOptionsSettings.Default); } else { this.Logger.Warning("Could not find a reader role for a reader with ID {0}.", game.Reader?.Id); } List <Task> addTeamRolesToChannel = new List <Task>(); foreach (Team team in game.Teams) { if (!roles.TeamRoles.TryGetValue(team, out IRole role)) { this.Logger.Warning("Team {name} did not have a role defined.", team.Name); continue; } // TODO: Investigate if it's possible to parallelize this. Other attempts to do so (Task.WhenAll, // AsyncEnumerable's ParallelForEachAsync) have had bugs where roles sometimes aren't assigned to a // channel. Adding an await in the loop seems to be the only thing that await this.AddPermission(channel, role); } await Task.WhenAll(addTeamRolesToChannel); this.Logger.Debug("Added permissions to text channel for room {0} in round {1}", roomNumber, roundNumber); return(channel); }