private void HandleIncomingMove(IgsLine igsLine) { string trim = igsLine.PureLine.Trim(); GameHeading heading = IgsRegex.ParseGameHeading(igsLine); if (heading != null) { IgsGame whatGame = this.GamesYouHaveOpened.Find(gm => gm.Info.IgsIndex == heading.GameNumber); if (whatGame == null) { // Do not remember this game, perhaps we're in match accept procedure return; } _incomingMovesAreForThisGame = whatGame; GetConnector(whatGame.Info).TimeControlAdjustment(new IgsTimeControlAdjustmentEventArgs(heading.WhiteTimeRemaining, heading.BlackTimeRemaining)); } else if (trim.Contains("Handicap")) { // 15 0(B): Handicap 3 int handicapStones = IgsRegex.ParseHandicapMove(igsLine); OnIncomingHandicapInformation(_incomingMovesAreForThisGame, handicapStones); } else { Match match = this._regexMove.Match(trim); string moveIndex = match.Groups[1].Value; string mover = match.Groups[2].Value; string coordinates = match.Groups[3].Value; string captures = match.Groups[4].Value; StoneColor moverColor = mover == "B" ? StoneColor.Black : StoneColor.White; Move move; if (coordinates == "Pass") { move = Move.Pass(moverColor); } else { move = Move.PlaceStone(moverColor, Position.FromIgsCoordinates(coordinates)); } string[] captureSplit = captures.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string capture in captureSplit) { move.Captures.Add(Position.FromIgsCoordinates(capture)); } HandleIncomingMove(_incomingMovesAreForThisGame, int.Parse(moveIndex), move); } }
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); } } }