package server; import java.io.IOException; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.time.Instant; import network.SocketWriter; import network.protocol.Packet; import network.protocol.PacketVisitor; import network.protocol.packets.*; import network.protocol.packets.ServerResponsePacket.Response; public class ServerConnexion implements PacketVisitor { private final Server server; private final InetSocketAddress clientAddress; private final SocketWriter writer; private String chatterName; public ServerConnexion(Server server, DatagramSocket socket, InetSocketAddress clientAddress) { this.clientAddress = clientAddress; this.server = server; this.writer = new SocketWriter(socket); } public String getChatterName() { return this.chatterName; } public void sendPacket(Packet packet) { try { this.writer.sendPacket(packet, clientAddress); } catch (IOException e) { e.printStackTrace(); this.server.removeConnexion(this); } } @Override public void visitPacket(CreateRoomPacket packet) { boolean created = server.createRoom(packet.getRoomName(), this); sendPacket(new ServerResponsePacket(created ? Response.RoomCreated : Response.RoomNotCreated)); if (created) onRoomJoin(); } @Override public void visitPacket(JoinRoomPacket packet) { if(server.getRoomName(this) != null) { server.leaveRoom(this); return; } boolean joined = server.joinRoom(packet.getRoomName(), this); sendPacket(new ServerResponsePacket(joined ? Response.RoomJoined : Response.RoomNotJoined)); if (joined) onRoomJoin(); } @Override public void visitPacket(LeaveRoomPacket packet) { String roomName = this.server.getRoomName(this); boolean left = server.leaveRoom(this); sendPacket(new ServerResponsePacket(left ? Response.RoomLeft : Response.RoomNotLeft)); if (left) onRoomLeave(roomName); } @Override public void visitPacket(LoginPacket packet) { if (packet.getPseudo().isEmpty() || server.hasChatterName(packet.getPseudo())) { sendPacket(new ServerResponsePacket(Response.AuthError)); return; } this.chatterName = packet.getPseudo(); sendPacket(new RoomListPacket(server.getRoomNames())); System.out.println("[Server] Chatter " + packet.getPseudo() + " connected !"); } @Override public void visitPacket(RequestRoomListPacket packet) { sendPacket(new RoomListPacket(server.getRoomNames())); } @Override public void visitPacket(SendChatMessagePacket packet) { boolean messageSent = server.sendToRoom(this, packet); sendPacket(new ServerResponsePacket(messageSent ? Response.MessageSent : Response.MessageNotSent)); } @Override public void visitPacket(DisconnectPacket packet) { this.onDisconnect(); } @Override public void visitPacket(HandshakePacket packet) { if(this.server.handleConnexionTime(this.clientAddress)) { System.out.println("[Server] Handshake received from " + clientAddress); } sendPacket(packet); } private void onDisconnect() { if (this.server.isInRoom(this)) { this.onRoomLeave(this.server.getRoomName(this)); } this.server.removeConnexion(this); System.out.println("[Server] Chatter " + chatterName + " disconnected !"); } private void onRoomJoin() { String joinMessage = "Chatter " + this.chatterName + " joined the room !"; this.server.sendToRoom(this, new ChatMessagePacket(Instant.now(), "", joinMessage)); } private void onRoomLeave(String roomName) { String joinMessage = "Chatter " + this.chatterName + " left the room !"; this.server.sendToRoom(roomName, new ChatMessagePacket(Instant.now(), "", joinMessage)); } @Override public void visitPacket(RoomListPacket packet) { // I'm never supposed to receive this from the client throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } @Override public void visitPacket(ChatMessagePacket packet) { // I'm never supposed to receive this from the client throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } @Override public void visitPacket(ServerResponsePacket packet) { // I'm never supposed to receive this from the client throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } @Override public void visitPacket(RequestActualRoomPacket packet) { sendPacket(new ActualRoomPacket(server.getRoomName(this))); } @Override public void visitPacket(ActualRoomPacket packet) { // I'm never supposed to receive this from the client throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } }