package network.server; import java.io.IOException; import java.net.Socket; import game.Game; import game.Player; import game.Game.GameState; import network.Connexion; import network.protocol.packets.ChangeCellPacket; import network.protocol.packets.ConnexionInfoPacket; import network.protocol.packets.DisconnectPacket; import network.protocol.packets.EndGamePacket; import network.protocol.packets.KeepAlivePacket; import network.protocol.packets.LoginPacket; import network.protocol.packets.PlayerJoinPacket; import network.protocol.packets.PlayerLeavePacket; import network.protocol.packets.StartGamePacket; import network.protocol.packets.UpdatePlayerScorePacket; import sudoku.io.SudokuSerializer; import sudoku.structure.Cell; import sudoku.structure.MultiDoku; public class ServerConnexion extends Connexion { private final Server server; private final KeepAliveHandler keepAliveHandler; private boolean shouldClose = false; private Player player = null; private MultiDoku doku; public ServerConnexion(Socket socket, Server server) throws IOException { super(socket); this.server = server; this.keepAliveHandler = new KeepAliveHandler(this); } public boolean update() { if (shouldClose || isClosed()) return false; return this.keepAliveHandler.update(); } public void nukeConnection() { if (player != null) { sendPacket(new DisconnectPacket("Le serveur a été fermé !")); this.server.broadcastPacket(new PlayerLeavePacket(player.getId())); this.server.getGame().removePlayer(player.getId()); } } @Override public synchronized void close() { if (shouldClose) return; super.close(); shouldClose = true; System.out.println("[Server] Closing connexion !"); } private void finishLogin() { // send players that have already joined (excluding this one) for (Player p : this.server.getGame().getPlayers().values()) { if (p.getId() != player.getId()) { sendPacket(new PlayerJoinPacket(p)); sendPacket(new UpdatePlayerScorePacket(p.getId(), p.getRemainingCells())); } } this.server.broadcastPacket(new PlayerJoinPacket(player)); sendPacket(new ConnexionInfoPacket(player.getId())); Game game = this.server.getGame(); if (game.getGameState() == GameState.GameGoing) { setSudoku(game.getDoku().clone()); sendPacket( new StartGamePacket(SudokuSerializer.serializeSudoku(game.getDoku()).toString(), game.getStartTime(), game.getGameDuration())); } } @Override public void visitPacket(KeepAlivePacket packet) { this.keepAliveHandler.recievedKeepAlive(packet.getKeepAliveId()); } @Override public void visitPacket(DisconnectPacket packet) { close(); } @Override public void visitPacket(LoginPacket packet) { if (this.player != null) return; this.player = this.server.addPlayer(packet.getPseudo()); finishLogin(); } @Override public void visitPacket(ConnexionInfoPacket packet) { throw new UnsupportedOperationException("Unimplemented method 'visitPacketConnexionInfo'"); } @Override public void visitPacket(PlayerJoinPacket packet) { throw new UnsupportedOperationException("Unimplemented method 'visitPacketPlayerJoin'"); } @Override public void visitPacket(PlayerLeavePacket packet) { throw new UnsupportedOperationException("Unimplemented method 'visitPacketPlayerLeave'"); } @Override public void visitPacket(StartGamePacket packet) { throw new UnsupportedOperationException("Unimplemented method 'visitPacketStartGame'"); } @Override public void visitPacket(EndGamePacket packet) { throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } @Override public void visitPacket(UpdatePlayerScorePacket packet) { throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } @Override public void visitPacket(ChangeCellPacket packet) { Cell cell = this.doku.getSubGrid(packet.getSudokuIndex()).getCell(packet.getCellIndex()); if (cell.getSymbolIndex() == Cell.NOSYMBOL && packet.getNewValue() == Cell.NOSYMBOL) return; if (cell.getSymbolIndex() != Cell.NOSYMBOL && packet.getNewValue() != Cell.NOSYMBOL) { cell.trySetValue(packet.getNewValue()); return; } if (cell.getSymbolIndex() != Cell.NOSYMBOL && packet.getNewValue() == Cell.NOSYMBOL) { cell.empty(); this.server.getGame().setPlayerRemainingCells(player, player.getRemainingCells() + 1); this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getRemainingCells())); return; } // on rajoute un chiffre à la grille if (cell.trySetValue(packet.getNewValue())) { this.server.getGame().setPlayerRemainingCells(player, player.getRemainingCells() - 1); this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getRemainingCells())); } checkWin(); } private void checkWin() { if (this.player.getRemainingCells() == 0) { this.server.stopGame(); } } public void setSudoku(MultiDoku doku) { this.doku = doku; assert (player != null); this.server.getGame().setPlayerRemainingCells(player, this.doku.getEmptyCells().size()); this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getRemainingCells())); } }