package server.threads; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.util.HashSet; import java.util.List; import server.GameServer; import server.event.ServerConnectionErrorEvent; import server.event.ServerIllegalMoveEvent; import server.event.ServerTimeoutEvent; import server.request.RequestBuilder; import util.gdl.factory.GdlFactory; import util.gdl.factory.exceptions.GdlFormatException; import util.gdl.grammar.GdlSentence; import util.http.HttpReader; import util.http.HttpWriter; import util.match.Match; import util.statemachine.Move; import util.statemachine.Role; import util.symbol.factory.exceptions.SymbolFormatException; public final class PlayRequestThread extends Thread { private final GameServer gameServer; private final String host; private final List<Move> legalMoves; private final Match match; private final int port; private final String playerName; private final List<Move> previousMoves; private final boolean unlimitedTime; private final Role role; private Move move; public PlayRequestThread(GameServer gameServer, Match match, List<Move> previousMoves, List<Move> legalMoves, Role role, String host, int port, String playerName, boolean unlimitedTime) { this.gameServer = gameServer; this.match = match; this.previousMoves = previousMoves; this.legalMoves = legalMoves; this.role = role; this.host = host; this.port = port; this.playerName = playerName; this.unlimitedTime = unlimitedTime; move = null; } public Move getMove() { return move; } @Override public void run() { try { InetAddress theHost = InetAddress.getByName(host); Socket socket = new Socket(theHost.getHostAddress(), port); String request = (previousMoves == null) ? RequestBuilder.getPlayRequest(match.getMatchId()) : RequestBuilder.getPlayRequest(match.getMatchId(), previousMoves); HttpWriter.writeAsClient(socket, theHost.getHostName(), request, playerName); String response = unlimitedTime ? HttpReader.readAsClient(socket) : HttpReader.readAsClient(socket, match.getPlayClock() * 1000 + 1000); move = gameServer.getStateMachine().getMoveFromSentence((GdlSentence) GdlFactory.create(response)); if (!new HashSet<Move>(legalMoves).contains(move)) { gameServer.notifyObservers(new ServerIllegalMoveEvent(role, move)); move = legalMoves.get(0); } socket.close(); } catch (SocketTimeoutException e) { gameServer.notifyObservers(new ServerTimeoutEvent(role)); move = legalMoves.get(0); } catch (IOException e) { gameServer.notifyObservers(new ServerConnectionErrorEvent(role)); move = legalMoves.get(0); } catch (GdlFormatException e) { gameServer.notifyObservers(new ServerIllegalMoveEvent(role, move)); move = legalMoves.get(0); } catch (SymbolFormatException e) { gameServer.notifyObservers(new ServerIllegalMoveEvent(role, move)); move = legalMoves.get(0); } } }