Esempio n. 1
0
        public async Task SetupFinalsAsync(IGuildUser readerUser, string rawTeamNameParts)
        {
            ITextChannel channel = null;

            await this.DoReadWriteActionOnCurrentTournamentAsync(
                async currentTournament =>
            {
                if (currentTournament?.Stage != TournamentStage.RunningTournament)
                {
                    this.Logger.Debug("Could not start finals in stage {stage}", currentTournament?.Stage);
                    await this.SendChannelMessage(BotStrings.ErrorFinalsOnlySetDuringPrelimsOrPlayoffs);
                    return;
                }

                if (!currentTournament.TryGetReader(readerUser.Id, out Reader reader))
                {
                    this.Logger.Debug("Could not start finals because {1} is not a reader", readerUser.Id);
                    await this.SendChannelMessage(BotStrings.ErrorGivenUserIsntAReader);
                    return;
                }

                if (rawTeamNameParts == null)
                {
                    this.Logger.Debug(
                        "Could not start finals because no teams were specified");
                    await this.SendChannelMessage(BotStrings.ErrorNoTeamsSpecified);
                    return;
                }

                string combinedTeamNames = string.Join(" ", rawTeamNameParts).Trim();
                if (!TeamNameParser.TryGetTeamNamesFromParts(
                        combinedTeamNames, out IList <string> teamNames, out string errorMessage))
                {
                    this.Logger.Debug(
                        "Could not start finals because of this error: {errorMessage}", errorMessage);
                    await this.SendChannelMessage(BotStrings.ErrorGenericMessage(errorMessage));
                    return;
                }

                if (teamNames.Count != 2)
                {
                    this.Logger.Debug(
                        "Could not start finals because {count} teams were specified", teamNames.Count);
                    await this.SendChannelMessage(BotStrings.ErrorTwoTeamsMustBeSpecifiedFinals(teamNames.Count));
                    return;
                }

                Team[] teams = teamNames.Select(name => new Team()
                {
                    Name = name
                })
                               .ToArray();
                if (currentTournament.Teams.Intersect(teams).Count() != teams.Length)
                {
                    this.Logger.Debug(
                        "Could not start finals because some teams were not in the tournament", teamNames.Count);
                    await this.SendChannelMessage(
                        BotStrings.ErrorAtLeastOneTeamNotInTournament(string.Join(", ", teamNames)));
                    return;
                }

                // Create a finals channel and give access to the teams and readers
                Game finalsGame = new Game()
                {
                    Reader = reader,
                    Teams  = teams
                };

                int finalsRoundNumber   = currentTournament.Schedule.Rounds.Count + 1;
                IList <Game> finalGames =
                    currentTournament.Schedule.Rounds[currentTournament.Schedule.Rounds.Count - 1].Games;
                int roomIndex = 0;
                foreach (Game game in finalGames)
                {
                    if (game.Reader.Equals(reader))
                    {
                        break;
                    }

                    roomIndex++;
                }

                if (roomIndex >= finalGames.Count)
                {
                    // Need to have a fall-back somehow. For now default to the first room.
                    roomIndex = 0;
                }

                // TODO: Look into creating the channels after the update stage so we can release the lock
                // sooner. However, this does mean that a failure to create channels will leave us in a bad
                // state.
                channel = await this.ChannelManager.CreateChannelsForFinals(
                    this.Context.Client.CurrentUser, currentTournament, finalsGame, finalsRoundNumber, roomIndex);

                currentTournament.UpdateStage(
                    TournamentStage.Finals, out string nextStageTitle, out string nextStageInstructions);
            });

            if (channel != null)
            {
                this.Logger.Debug("Finals started successfully");
                await this.Context.Channel.SendMessageAsync(
                    BotStrings.FinalsParticipantsPleaseJoin(channel.Mention),
                    options : RequestOptionsSettings.Default);
            }
        }