package server; import java.io.IOException; import java.net.InetSocketAddress; import java.time.Instant; import network.Socket; 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 Socket socket; private String chatterName; public ServerConnexion(Server server, Socket socket, InetSocketAddress clientAddress) { this.clientAddress = clientAddress; this.server = server; this.socket = socket; } public String getChatterName() { return this.chatterName; } public void sendPacket(Packet packet) { try { this.socket.sendPacket(packet, clientAddress); } catch (IOException e) { e.printStackTrace(); this.server.removeConnexion(this); } } /** * Check if the client is logged in * @return true if the client is logged in */ private boolean checkLogin() { if (this.chatterName != null && this.chatterName.isEmpty()) { sendPacket(new ServerResponsePacket(Response.AuthError)); return false; } return true; } /** * Make the server create a room & enter it * @param packet the packet containing the room name */ @Override public void visitPacket(CreateRoomPacket packet) { if (!checkLogin()) return; boolean created = server.createRoom(packet.getRoomName(), this); sendPacket(new ServerResponsePacket(created ? Response.RoomCreated : Response.RoomNotCreated)); if (created) onRoomJoin(); } /** * Make the server join a room * @param packet the packet containing the room name */ @Override public void visitPacket(JoinRoomPacket packet) { if (!checkLogin()) return; 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(); } /** * Make the server leave a room * @param packet the packet containing the room name */ @Override public void visitPacket(LeaveRoomPacket packet) { if (!checkLogin()) return; String roomName = this.server.getRoomName(this); boolean left = server.leaveRoom(this); sendPacket(new ServerResponsePacket(left ? Response.RoomLeft : Response.RoomNotLeft)); if (left) onRoomLeave(roomName); } /** * Checks if the pseudo is available (nobody connected with the same pseudo) * @param packet the packet containing the pseudo */ @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 ServerResponsePacket(Response.AuthSuccess)); sendPacket(new RoomListPacket(server.getRoomNames())); System.out.println("[Server] Chatter " + packet.getPseudo() + " connected !"); } /** * Get the list of rooms * @param packet the packet containing the request */ @Override public void visitPacket(RequestRoomListPacket packet) { if (!checkLogin()) return; sendPacket(new RoomListPacket(server.getRoomNames())); } /** * Send a message to the room * @param packet the packet containing the message */ @Override public void visitPacket(SendChatMessagePacket packet) { if (!checkLogin()) return; boolean messageSent = server.sendToRoom(this, packet); sendPacket(new ServerResponsePacket(messageSent ? Response.MessageSent : Response.MessageNotSent)); } /** * Disconnect the client * @param packet the packet containing the request */ @Override public void visitPacket(DisconnectPacket packet) { this.onDisconnect(); } /** * Remove all room connections while disconnecting the client */ private void onDisconnect() { if (this.server.isInRoom(this)) { this.onRoomLeave(this.server.getRoomName(this)); } this.server.removeConnexion(this); if (chatterName != null) System.out.println("[Server] Chatter " + chatterName + " disconnected !"); } /** * Send a message to the room when a client joins */ private void onRoomJoin() { String joinMessage = "Chatter " + this.chatterName + " joined the room !"; this.server.sendToRoom(this, new ChatMessagePacket(Instant.now(), "", joinMessage)); } /** * Send a message to the room when a client leaves * @param roomName the name of the room */ 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'"); } }