private void clientComm(object p) { bool isready = false; int bytesRead; Player threadPlayer = (Player)p; TcpClient threadClient = threadPlayer.Tcp(); NetworkStream threadStream = threadPlayer.Stream(); byte[] buffer = new byte[255]; byte[] start = Encoding.GetEncoding("UTF-8").GetBytes("START\n"); byte[] abnormal = Encoding.GetEncoding("UTF-8").GetBytes("#ABNORMAL\n"); byte[] gameover = Encoding.GetEncoding("UTF-8").GetBytes("#GAME_OVER\n"); byte[] illegal = Encoding.GetEncoding("UTF-8").GetBytes("#ILLEGAL\n"); byte[] win = Encoding.GetEncoding("UTF-8").GetBytes("#WIN\n"); byte[] lose = Encoding.GetEncoding("UTF-8").GetBytes("#LOSE\n"); byte[] draw = Encoding.GetEncoding("UTF-8").GetBytes("#DRAW\n"); while (true) { // wait for data to come in try { bytesRead = threadStream.Read(buffer, 0, 255); string bufferStr = Encoding.UTF8.GetString(buffer); if (!threadPlayer.Opponent().Tcp().Connected) { break; } if (!isready && bufferStr.StartsWith("AGREE")) { threadPlayer.Stream().Write(start, 0, start.Length); isready = true; continue; } // if client clicks cancel if (bytesRead == 0) { if (threadPlayer.Opponent() != null) { if (threadPlayer.Opponent().Tcp().Connected == true) { // tell opponent game ended threadPlayer.Opponent().Stream().Write(abnormal, 0, abnormal.Length); } } break; } // resign else if (bufferStr.StartsWith("resign")) { //tell opponent game ended threadPlayer.Opponent().Stream().Write(gameover, 0, gameover.Length); threadPlayer.Opponent().Stream().Write(win, 0, win.Length); break; } else if (bufferStr.StartsWith("+") || (bufferStr.StartsWith("-"))) // white move { // 処理中に対局が無くなると死ぬ int gameIdx = -1; for (int i = 0; i < games.Count; i++) { if (games[i].Id() == threadPlayer.GameId()) { gameIdx = i; } } if (gameIdx == -1) { Console.WriteLine("ERROR"); break; } Move move = new Move(bufferStr.Substring(1, 6)); // illegal move if ((bufferStr.StartsWith("+") && threadPlayer.MyColor() != Color.WHITE) || (bufferStr.StartsWith("-") && threadPlayer.MyColor() != Color.BLACK) || !games[gameIdx].pos.IsLegalMove(move)) { threadPlayer.Stream().Write(illegal, 0, illegal.Length); threadPlayer.Stream().Write(lose, 0, lose.Length); //tell opponent game ended threadPlayer.Opponent().Stream().Write(gameover, 0, gameover.Length); threadPlayer.Opponent().Stream().Write(win, 0, win.Length); break; } // OKを送る string mStr = (move.Promote() ? bufferStr.Substring(1, 6) : bufferStr.Substring(1, 5)) + ",OK"; byte[] ok = Encoding.GetEncoding("UTF-8").GetBytes(mStr); threadPlayer.Stream().Write(ok, 0, ok.Length); threadPlayer.Opponent().Stream().Write(ok, 0, ok.Length); // do move if (games[gameIdx].pos.DoMove(move)) { threadPlayer.Stream().Write(gameover, 0, gameover.Length); threadPlayer.Stream().Write(win, 0, win.Length); //tell opponent game ended threadPlayer.Opponent().Stream().Write(gameover, 0, gameover.Length); threadPlayer.Opponent().Stream().Write(lose, 0, win.Length); break; } } // chat else { threadPlayer.Opponent().Stream().Write(buffer, 0, bytesRead); } } // Client closed catch (System.IO.IOException) { // tell opponent game ended if (threadPlayer.Opponent() != null) { threadPlayer.Opponent().Stream().Write(abnormal, 0, abnormal.Length); } break; } } Console.WriteLine("Player #" + threadPlayer.PlayerId() + " left"); threadStream.Close(); threadClient.Close(); lock (waitingPlayerLock) { if (waitingPlayer != null) { if (waitingPlayer.PlayerId() == threadPlayer.PlayerId()) { waitingPlayer = null; } } } // find game from gameID and see if can remove from list lock (gamesLock) { for (int i = 0; i < games.Count; i++) { if (games[i].Id() == threadPlayer.GameId()) { if (threadPlayer.Opponent() != null) { if (games[i].Player1().Tcp().Connected == false && games[i].Player2().Tcp().Connected == false) { games.RemoveAt(i); break; } } } } } }