Coverage Summary for Class: ClientHandler (it.polimi.ingsw.gc14.Network.TCP.Server)

Class Class, % Method, % Branch, % Line, %
ClientHandler 0% (0/1) 0% (0/6) 0% (0/14) 0% (0/31)


 package it.polimi.ingsw.gc14.Network.TCP.Server;
 
 import it.polimi.ingsw.gc14.LimitedMap;
 import it.polimi.ingsw.gc14.Model.MiniModel;
 import it.polimi.ingsw.gc14.Network.NetworkEvent;
 import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer;
 
 import java.io.*;
 import java.net.*;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
 
 /**
  * Handles the TCP connection with a single client.
  * Each instance runs on a dedicated thread and is responsible for receiving {@link NetworkEvent} from its client and adding them
  * to the {@link #actionQueue}.
  * It is also responsible to send events and game model updates back to the client.
  */
 public class ClientHandler implements Runnable {
     /**
      * The username of the connected client on this handler
      */
     private final String username;
     /** {@code true} while the handler is actively reading from the socket; set to {@code false} on disconnect. */
     private volatile boolean running;
 
     /**
      * Returns the username associated with this client.
      *
      * @return the username associated with this client.
      */
     public String getUsername() {
         return username;
     }
     /** The TCP socket */
     private final Socket clientSocket;
 
     /** Input stream used to receive objects from the client */
     private final ObjectInputStream in;
 
     /** Output stream used to send objects to the client */
     private final ObjectOutputStream out;
 
     /**
      * Shared list of all client handlers.
      * This handler removes itself from the list when disconnected.
      */
     private final List<ClientHandler> clientHandlers;
 
     /** Maps each connected player's username to their connection state (true = connected). */
     private final LimitedMap<String, Boolean> limitedMap;
 
     /** Queue containing the events to be applied to the game model */
     private final BlockingQueue<NetworkEvent> actionQueue;
 
 
     /**
      * Class constructor that initializes the attributes.
      *
      * @param username       the username associated with the client.
      * @param clientSocket   the socket representing the client's TCP connection.
      * @param out            the output stream used to send data to the client.
      * @param in             the input stream used to receive data from the client.
      * @param clientHandlers the shared list of all active client handlers.
      * @param playersMap     the shared map containing the connected players.
      * @param actionQueue    the queue containing incoming events.
      */
     public ClientHandler(String username, Socket clientSocket, ObjectOutputStream out, ObjectInputStream in, List<ClientHandler> clientHandlers, LimitedMap<String,Boolean> playersMap, BlockingQueue<NetworkEvent> actionQueue) {
         this.username=username;
         this.clientSocket = clientSocket;
         this.in = in;
         this.out = out;
         this.clientHandlers = clientHandlers;
         this.actionQueue = actionQueue;
         this.limitedMap = playersMap;
     }
 
 
     /**
      * Listens for incoming {@link NetworkEvent}s from the client and adds them to the {@link #actionQueue}.
      * Upon disconnection, this handler removes itself from {@link #clientHandlers}.
      */
     @Override
     public void run() {
         running = true;
         try {
             while (running) {
                 NetworkEvent event = (NetworkEvent) in.readObject();
                 if (!actionQueue.offer(event)) {
                     System.out.println("Error inserting action into queue");
                 }
             }
         } catch (IOException e) {
         } catch (ClassNotFoundException e) {
             System.err.println("Class not found: " + username);
         } finally {
             if (running) disconnect();
         }
     }
 
 
 
     /**
      * Sends a {@link NetworkEvent} to the client.
      * @param event The network event to send to the client.
      */
     public synchronized void notifyEvent(NetworkEvent event) {
         try {
             out.reset();
             out.writeObject(event);
         } catch (IOException e) {
             e.printStackTrace();
             disconnect();
         }
 
     }
 
 
     /**
      * Sends the current game model to this client.
      * @param game The current state of the game to send to the client.
      */
     public synchronized void notifyMiniModel(MiniModel game) {
         try {
             out.reset();
             out.writeObject(game);
         } catch (IOException e) {
             e.printStackTrace();
             disconnect();
         }
     }
 
     /**
      * Disconnects the client from the server.
      *
      * <p>The client handler is stopped and removed from the list of active handlers.
      * The player is marked as disconnected, a {@link DisconnectedPlayer} event is
      * added to the action queue, and the associated socket is closed.
      */
     public synchronized void disconnect() {
         if (!running) return;
         running = false;
         clientHandlers.remove(this);
         limitedMap.put(username, false);
         actionQueue.add(new DisconnectedPlayer(username));
         System.err.println("(TCP) Disconnected player: " + username);
         try { clientSocket.close(); } catch (IOException ignored) {}
     }
 }