public async Task <IgsGame> AcceptMatchRequestAsync(IgsMatchRequest matchRequest) { // We are accepting a match and it begins. var lines = await MakeRequestAsync(matchRequest.AcceptCommand); if (lines.IsError) { return(null); } if (lines.Any(ln => ln.Code == IgsCode.Info && ln.PureLine.Contains("Requesting"))) { this.igsConnection.Events.OnErrorMessageReceived("Requesting " + matchRequest.OpponentName + " to confirm match."); return(null); } var heading = this.igsConnection.Data.LastReceivedGameHeading; var ogi = await GetGameByIdAsync(heading.GameNumber); var builder = GameBuilder.CreateOnlineGame(ogi).Connection(this.igsConnection); bool youAreBlack = heading.BlackName == this.igsConnection.Username; var humanPlayer = new HumanPlayerBuilder(youAreBlack ? StoneColor.Black : StoneColor.White).Name(youAreBlack ? heading.BlackName : heading.WhiteName) .Rank(youAreBlack ? ogi.Black.Rank : ogi.White.Rank) .Clock(new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(ogi.ByoyomiPeriod))) .Build(); var onlinePlayer = new IgsPlayerBuilder(youAreBlack ? StoneColor.White : StoneColor.Black, this.igsConnection).Name( youAreBlack ? heading.WhiteName : heading.BlackName) .Rank(youAreBlack ? ogi.White.Rank : ogi.Black.Rank) .Clock(new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(ogi.ByoyomiPeriod))) .Build(); builder.BlackPlayer(youAreBlack ? humanPlayer : onlinePlayer) .WhitePlayer(youAreBlack ? onlinePlayer : humanPlayer); var game = builder.Build(); this.igsConnection.GamesYouHaveOpened.Add(game); return(game); }
private async void HandleFullInterrupt(List <IgsLine> currentLineBatch) { if (currentLineBatch.Count > 0) { if (currentLineBatch.Any(line => line.Code == IgsCode.Status)) { var infoLine = currentLineBatch.FirstOrDefault(ln => ln.Code == IgsCode.Info); if (infoLine != null) { ScoreLine scoreLine = IgsRegex.ParseObservedScoreLine(infoLine); if (scoreLine != null) { IgsGame gameInfo = this.GamesYouHaveOpened.FirstOrDefault(gi => gi.Info.IgsIndex == scoreLine.GameId); if (gameInfo != null) { ScoreGame(gameInfo, scoreLine.BlackScore, scoreLine.WhiteScore); } } } } if (currentLineBatch.Any(line => line.PureLine.EndsWith("accepted.") && line.Code == IgsCode.Info)) { // An outgoing match request has been accepted by another player and the game can begin. GameHeading heading = this.Data.LastReceivedGameHeading; var ogi = await Commands.GetGameByIdAsync(heading.GameNumber); var builder = GameBuilder.CreateOnlineGame(ogi).Connection(this); bool youAreBlack = ogi.Black.Name == _username; bool youAreWhite = ogi.White.Name == _username; if (youAreBlack) { builder.BlackPlayer( new HumanPlayerBuilder(StoneColor.Black) .Name(ogi.Black.Name) .Rank(ogi.Black.Rank) .Clock(new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(ogi.ByoyomiPeriod)).UpdateFrom(heading.BlackTimeRemaining)) .Build()); } else { builder.BlackPlayer( new IgsPlayerBuilder(StoneColor.Black, this) .Name(ogi.Black.Name) .Rank(ogi.Black.Rank) .Clock(new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(ogi.ByoyomiPeriod)).UpdateFrom(heading.BlackTimeRemaining)) .Build()); } if (youAreWhite) { builder.WhitePlayer( new HumanPlayerBuilder(StoneColor.White) .Name(ogi.White.Name) .Rank(ogi.White.Rank) .Clock(new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(ogi.ByoyomiPeriod)).UpdateFrom(heading.WhiteTimeRemaining)) .Build()); } else { builder.WhitePlayer( new IgsPlayerBuilder(StoneColor.White, this) .Name(ogi.White.Name) .Rank(ogi.White.Rank) .Clock(new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(ogi.ByoyomiPeriod)).UpdateFrom(heading.WhiteTimeRemaining)) .Build()); } IgsGame newGame = builder.Build(); this.GamesYouHaveOpened.Add(newGame); Events.OnMatchRequestAccepted(newGame); } if (currentLineBatch.Any(line => line.PureLine.Contains("Creating match") && line.Code == IgsCode.Info)) { // Make it not be an interrupt and let it be handled by the match creator. foreach (IgsLine line in currentLineBatch) { lock (this._mutex) { if (this._requestInProgress != null) { this._requestInProgress.IncomingLines.Post(line); } else { if (this.Composure == IgsComposure.Ok) { Events.OnUnhandledLine(line.EntireLine); } } } } } if (currentLineBatch.Count == 3 && currentLineBatch[0].Code == IgsCode.SayInformation && currentLineBatch[1].Code == IgsCode.Say) { int gameNumber = IgsRegex.ParseGameNumberFromSayInformation(currentLineBatch[0]); ChatMessage chatLine = IgsRegex.ParseSayLine(currentLineBatch[1], this); IgsGame relevantGame = this.GamesYouHaveOpened.Find(gi => gi.Info.IgsIndex == gameNumber); if (relevantGame == null) { // We received a chat message for a game we no longer play. return; } if (chatLine.Text.StartsWith(gameNumber + " ")) { chatLine.Text = chatLine.Text.Substring((gameNumber + " ").Length); } GetConnector(relevantGame.Info).ChatMessageFromServer(chatLine); } if (currentLineBatch[0].Code == IgsCode.Kibitz && currentLineBatch.Count >= 2) { // 11 Kibitz ([^ ]+).*\[([0-9]+)\] Tuple <string, int> firstLine = IgsRegex.ParseKibitzHeading(currentLineBatch[0]); string text = currentLineBatch[1].PureLine.Trim(); IgsGame relevantGame = this.GamesYouHaveOpened.Find(gi => gi.Info.IgsIndex == firstLine.Item2); GetConnector(relevantGame.Info).ChatMessageFromServer(new ChatMessage(firstLine.Item1, text, DateTimeOffset.Now, firstLine.Item1 == this.Username ? ChatMessageKind.Outgoing : ChatMessageKind.Incoming)); } if (currentLineBatch[0].Code == IgsCode.Tell && currentLineBatch[0].PureLine.StartsWith("*SYSTEM*") && currentLineBatch[0].PureLine.EndsWith("requests undo.")) { string requestingUser = IgsRegex.WhoRequestsUndo(currentLineBatch[0]); var games = GetGamesIncluding(requestingUser); if (games.Any()) { foreach (var game in games) { Events.OnUndoRequestReceived(game.Info); } } else { throw new Exception("Received an undo request for a game that's not in progress."); } this._ignoreNextPrompt = true; } if (currentLineBatch[0].Code == IgsCode.Undo) { int numberOfMovesToUndo = currentLineBatch.Count(line => line.Code == IgsCode.Undo); IgsLine gameHeadingLine = currentLineBatch.Find(line => line.Code == IgsCode.Move); int game = IgsRegex.ParseGameNumberFromHeading(gameHeadingLine); IgsGame gameInfo = this.GamesYouHaveOpened.Find(gi => gi.Info.IgsIndex == game); for (int i = 0; i < numberOfMovesToUndo; i++) { GetConnector(gameInfo.Info).ForceMainUndo(); } } if (currentLineBatch[0].EntireLine.Contains("'done'")) { IgsLine gameHeadingLine = currentLineBatch.Find(line => line.Code == IgsCode.Move); int gameIndex = IgsRegex.ParseGameNumberFromHeading(gameHeadingLine); _availableConnectors[gameIndex].SetPhaseFromServer(GamePhaseType.LifeDeathDetermination); } if (currentLineBatch.Any(ln => ln.Code == IgsCode.Score)) { ScoreLine scoreLine = IgsRegex.ParseScoreLine(currentLineBatch.Find(ln => ln.Code == IgsCode.Score)); IgsGame gameInfo = this.GamesYouHaveOpened.Find(gi => gi.Info.White.Name == scoreLine.White && gi.Info.Black.Name == scoreLine.Black); ScoreGame(gameInfo, scoreLine.BlackScore, scoreLine.WhiteScore); } } }
public async Task <IgsGame> StartObserving(IgsGameInfo gameInfo) { if (this.igsConnection.GamesBeingObserved.Any(g => g.Info.IgsIndex == gameInfo.IgsIndex)) { // We are already observing this game. return(null); } var response = await MakeRequestAsync("observe " + gameInfo.IgsIndex); if (response.IsError) { // Observing failed. return(null); } var heading = response.GetGameHeading(); if (heading == null) { return(null); } if (heading.BlackName != gameInfo.Black.Name || heading.WhiteName != gameInfo.White.Name) { // It's a different game now. return(null); } TimeControl blackClock = new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(gameInfo.ByoyomiPeriod)).UpdateFrom( heading.BlackTimeRemaining); TimeControl whiteClock = new CanadianTimeControl(TimeSpan.Zero, 25, TimeSpan.FromMinutes(gameInfo.ByoyomiPeriod)).UpdateFrom( heading.WhiteTimeRemaining); if (heading.BlackTimeRemaining.PeriodStonesLeft == 0 && heading.BlackTimeRemaining.PeriodTimeLeft == TimeSpan.Zero && heading.BlackTimeRemaining.MainTimeLeft == TimeSpan.Zero) { blackClock = new NoTimeControl(); whiteClock = new NoTimeControl(); } var titleLine = response.LastOrDefault(line => line.Code == IgsCode.Info); string gameName = null; if (titleLine != null) { gameName = IgsRegex.ParseTitleInformation(titleLine); } var blackPlayer = new IgsPlayerBuilder(StoneColor.Black, this.igsConnection) .Name(gameInfo.Black.Name) .Rank(gameInfo.Black.Rank) .Clock(blackClock) .Build(); var whitePlayer = new IgsPlayerBuilder(StoneColor.White, this.igsConnection) .Name(gameInfo.White.Name) .Rank(gameInfo.White.Rank) .Clock(whiteClock) .Build(); var onlineGame = GameBuilder.CreateOnlineGame(gameInfo) .Connection(this.igsConnection) .BlackPlayer(blackPlayer) .WhitePlayer(whitePlayer) .Ruleset(RulesetType.Japanese) .Komi(gameInfo.Komi) .BoardSize(gameInfo.BoardSize) .Name(gameName) .Build(); this.igsConnection.GamesBeingObserved.Add(onlineGame); this.igsConnection.GamesYouHaveOpened.Add(onlineGame); this.igsConnection.MakeUnattendedRequest("moves " + gameInfo.IgsIndex); return(onlineGame); }