package javass.net; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import static javass.net.StringSerializer.*; import javass.jass.Card; import javass.jass.Card.Color; import javass.jass.CardSet; import javass.jass.Player; import javass.jass.PlayerId; import javass.jass.Score; import javass.jass.TeamId; import javass.jass.Trick; import javass.jass.TurnState; /** * Connects to a remote client and executes functions according to the data * sent. * * @author Charles BEAUVILLE * @author Celia HOUSSIAUX * */ public final class RemotePlayerServer { private static final int PORT_NUMBER = 5108; private static final int COMMAND_INDEX = 0; private static final int ARG_0_INDEX = 0; private static final int ARG_1_INDEX = 1; private static final int ARG_2_INDEX = 2; private Player localPlayer; /** * Connects to a remote client and executes functions of the given player * according to the data sent. * * @param p * the underlying player. */ public RemotePlayerServer(Player p) { this.localPlayer = p; } /** * Runs the server on the port number. * @throws IOException */ public void run() throws IOException { @SuppressWarnings("resource") //Listens for a connection on the port number. ServerSocket s0 = new ServerSocket(PORT_NUMBER); Socket s = s0.accept(); //Sets up the buffers to read and to write on the socket. BufferedReader r = new BufferedReader(new InputStreamReader( s.getInputStream(), StandardCharsets.UTF_8)); BufferedWriter w = new BufferedWriter(new OutputStreamWriter( s.getOutputStream(), StandardCharsets.UTF_8)); String command; //Reads the commands wrote on the socket line per line while ((command = r.readLine()) != null) { String[] msg = split(' ', command); switch (JassCommand.valueOf(msg[COMMAND_INDEX])) { case PLRS: //Creates the players map with the arguments and calls the setPlayers function of the underlyingPlayer. Map players = new HashMap<>(); for (int i = 0; i < PlayerId.COUNT; i++) { players.put(PlayerId.ALL.get(i), deserializeString(split(',', msg[ARG_2_INDEX])[i])); } localPlayer.setPlayers(PlayerId.ALL.get(deserializeInt(msg[ARG_1_INDEX])), players); break; case CARD: //Calls the cardToPlay function of the underlying function with the arguments of the message. String[] st = split(',', msg[ARG_1_INDEX]); TurnState state = TurnState.ofPackedComponents( deserializeLong(st[ARG_0_INDEX]), deserializeLong(st[ARG_1_INDEX]), deserializeInt(st[ARG_2_INDEX])); Card c = localPlayer.cardToPlay(state, CardSet.ofPacked(deserializeLong(msg[ARG_2_INDEX]))); w.write(serializeInt(c.packed())); w.newLine(); w.flush(); break; case HAND: localPlayer .updateHand(CardSet.ofPacked(deserializeLong(msg[ARG_1_INDEX]))); break; case TRMP: localPlayer.setTrump(Color.ALL.get(deserializeInt(msg[ARG_1_INDEX]))); break; case SCOR: localPlayer .updateScore(Score.ofPacked(deserializeLong(msg[ARG_1_INDEX]))); break; case TRCK: localPlayer.updateTrick(Trick.ofPacked(deserializeInt(msg[ARG_1_INDEX]))); break; case WINR: localPlayer .setWinningTeam(TeamId.ALL.get(deserializeInt(msg[ARG_1_INDEX]))); break; default: } } } }