Coverage Summary for Class: ClientReader (it.polimi.ingsw.Client.CLI)

Class Class, % Method, % Branch, % Line, %
ClientReader 0% (0/1) 0% (0/6) 0% (0/38) 0% (0/109)


1 package it.polimi.ingsw.Client.CLI; 2  3 import it.polimi.ingsw.Network.SocketWrapper; 4 import it.polimi.ingsw.Server.Messages.Message; 5 import it.polimi.ingsw.Server.Messages.ServerResponses.*; 6 import it.polimi.ingsw.Server.Messages.ServerResponses.SupportStructures.StatusCode; 7  8 import java.io.IOException; 9 import java.util.List; 10 import java.util.UUID; 11 import java.util.concurrent.CyclicBarrier; 12  13 public class ClientReader implements Runnable { 14  /** 15  * The reference to the CLIWriter class (used only in CLI mode) 16  */ 17  18  final CyclicBarrier cyclicBarrier; 19  /** 20  * The socketWrapper used to receive messages from the server 21  */ 22  private final SocketWrapper socketWrapper; 23  /** 24  * The object used to store the client's game data 25  */ 26  private final ClientView clientView; 27  28  29  //CLI-only constructor 30  public ClientReader(SocketWrapper socketWrapper, ClientView clientView, CyclicBarrier cyclicBarrier) { 31  this.socketWrapper = socketWrapper; 32  this.clientView = clientView; 33  this.cyclicBarrier = cyclicBarrier; 34  } 35  36  /** 37  * Keep listening the socket 38  */ 39  @Override 40  public void run() { 41  //create Message object 42  Message response; 43  while (true) { 44  try { 45  //get message from Server 46  response = socketWrapper.awaitMessage(); 47  } catch (IOException ex) { 48  System.err.println("Server connection lost."); 49  this.clientView.disconnectViewFromServer(); 50  break; 51  } 52  if (response == null) { 53  System.err.println("Server connection lost."); 54  this.clientView.disconnectViewFromServer(); 55  break; 56  } 57  58  //Elaborate the message from the server 59  try { 60  AnalyzeResponse(response); 61  } catch (IOException e) { 62  System.out.println("Error related to I/O "); 63  } catch (Exception e) { 64  throw new RuntimeException(e); 65  } 66  } 67  68  } 69  70  /** 71  * Method responsible for analyze Server's response and modify client's view basing on response 72  * Furthermore it prints some useful information to update the player 73  * 74  * @param serverResponse message received from Server 75  * @throws Exception Necessary to handle synchronization and view's update's exceptions 76  */ 77  private void AnalyzeResponse(Message serverResponse) throws Exception { 78  switch (serverResponse) { 79  case PlayerActionFeedback playerActionFeedback -> { 80  if (playerActionFeedback.getStatusCode() == StatusCode.Fail) 81  System.out.println(playerActionFeedback.getReport()); 82  } 83  //Server's response received after requesting a connection 84  case Welcome welcome -> { 85  //check if Client was able to connect to Server 86  if (welcome.getStatusCode() == StatusCode.Success) { 87  ClearCLI(); 88  System.out.println("Successfully connected to the server"); 89  //notify view that Client has connected 90  this.clientView.setConnected(true); 91  } else { 92  System.out.println("Something gone wrong, connection not established"); 93  } 94  //Notify CliWriter thread that Client has connected 95  this.cyclicBarrier.await(); 96  } 97  //Server's responde received after sending a DeclarePlayerRequest 98  case LobbyServerAccept response -> { 99  //check if client was able to log the Server 100  if (response.getStatusCode() == StatusCode.Success) { 101  //notify view that Client has logged 102  this.clientView.setLogged(true); 103  System.out.println("User accepted\n"); 104  //check for openLobbies availability 105  if (response.getPublicLobbies().size() == 0) { 106  System.out.println("No open lobbies available"); 107  } else { 108  System.out.println("Available open lobbies:"); 109  //print available openLobbies 110  response.getPublicLobbies().forEach(lobbyInfo -> System.out.println("ID: " + lobbyInfo.getID() + " admin: " + lobbyInfo.getAdmin())); 111  } 112  System.out.println("type 'showActions' for a list of available actions during all the game"); 113  } else { 114  System.out.println("Password wrong for this username, try again or change Username"); 115  } 116  //Notify CliWriter thread that now Client has logged 117  this.cyclicBarrier.await(); 118  } 119  //Server's response received after sending a joinLobbyRequest or CreateLobbyRequest 120  case LobbyConnected response -> { 121  //check if client was able to join the selected lobby 122  if (response.getStatusCode() == StatusCode.Success) { 123  //get Lobby's UUID 124  UUID id = response.getLobbyID(); 125  System.out.println("Joined to lobby, id: " + id + " admin:" + response.getAdmin()); 126  //update lobby's Admin's nickname inside Client's view 127  clientView.setAdmin(response.getAdmin()); 128  //notify Client's view that Client has logged 129  clientView.setIsInLobby(true); 130  } else { 131  System.out.println("Something gone wrong, lobby not joined"); 132  } 133  } 134  //Server's response received when the lobby has been closed for some reason 135  case LobbyClosed lobbyClosed -> { 136  //check if the lobby has been closed 137  if (lobbyClosed.getStatusCode() == StatusCode.Success) { 138  if (!this.clientView.isGameEnded()) { 139  //if the lobby was closed before the end of the game clear cli before print any other message 140  ClearCLI(); 141  System.out.println("The lobby has been closed; you can now join or create a lobby"); 142  //notify lobby that Client left lobby and game 143  this.clientView.disconnectView(); 144  } else { 145  System.out.println("\nThe lobby has been closed; you can now join or create a lobby"); 146  //notify lobby that Client left lobby and game 147  this.clientView.disconnectView(); 148  } 149  } else System.out.println("Something gone wrong, lobby not closed"); 150  } 151  //Server's response received when one player connected to the Lobby 152  case ClientConnected clientConnected -> { 153  if (clientConnected.getStatusCode() == StatusCode.Success) { 154  System.out.println("player " + clientConnected.getLastConnectedNickname() + " has connected"); 155  System.out.println("Players connected:"); 156  //print all connected players' nicknames 157  clientConnected.getPlayers().forEach(System.out::println); 158  } 159  } 160  //Server's response received when one player disconnected from the Lobby 161  case ClientDisconnected clientDisconnected -> { 162  if (clientDisconnected.getStatusCode() == StatusCode.Success) { 163  //Only if the disconnection takes place before the game has started other waiting players should be notified of the disconnection 164  if (!this.clientView.getGameStarted()) { 165  System.out.println("player " + clientDisconnected.getLastDisconnectedNickname() + " has disconnected"); 166  System.out.println("Players connected:"); 167  //print all connected players' nicknames 168  clientDisconnected.getPlayers().forEach(System.out::println); 169  } 170  } else { 171  System.out.println("Something gone wrong, client not disconnected"); 172  } 173  } 174  //Server's response received when Admin is starting the game 175  case GameInit response -> { 176  if (response.getStatusCode() == StatusCode.Fail) { 177  System.out.println(response.getErrorMessage()); 178  } else { 179  System.out.println("Game is starting..."); 180  } 181  } 182  //Server's response received when game has started 183  case GameStarted ignored -> { 184  System.out.println("The game has started"); 185  //notify Client's view that the game has started 186  clientView.setGameStarted(true); 187  } 188  //Server's response containing updated model to show 189  case ModelUpdated modelUpdated -> { 190  //Update lobby's model 191  this.clientView.setGame(modelUpdated.getModel()); 192  UpdateView(); 193  } 194  //Server's response received when the game ended after a victory 195  case GameOver gameOver -> { 196  //notify Client's view that the game has ended 197  this.clientView.setGameEnded(true); 198  UpdateViewWin(gameOver.getWinners()); 199  } 200  case InvalidRequest ignored -> 201  System.out.println("Something gone wrong, your request has not been executed"); 202  default -> System.out.println("Received an unexpected server's response:" + serverResponse.getClass()); 203  } 204  } 205  206  /** 207  * This method clears Client's console 208  */ 209  210  private void ClearCLI() { 211  try { 212  final String operatingSystem = System.getProperty("os.name"); 213  if (operatingSystem.contains("Windows")) { 214  new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); 215  } else { 216  System.out.print("\033\143"); 217  } 218  } catch (Exception e) { 219  System.out.println("Clear operation failed"); 220  } 221  } 222  223  /** 224  * Support method responsible for clearing CLI and print updated model by using view's printing methods, not used to print winners 225  */ 226  private void UpdateView() { 227  ClearCLI(); 228  this.clientView.printView(); 229  } 230  231  /** 232  * Support method responsible for printing game's winners 233  * 234  * @param winners list of String containing winners' nicknames 235  */ 236  private void UpdateViewWin(List<String> winners) { 237  ClearCLI(); 238  System.out.println(""" 239  240  _ __ __ _ ____ 241  | | / /__ / /_ ____ __ _____ ____ _ _ __(_)___ ____ ___ _____/ / / 242  | | /| / / _ \\ / __ \\/ __ `/ | / / _ \\ / __ `/ | | /| / / / __ \\/ __ \\/ _ \\/ ___/ / /\s 243  | |/ |/ / __/ / / / / /_/ /| |/ / __/ / /_/ / | |/ |/ / / / / / / / / __/ / /_/_/ \s 244  |__/|__/\\___/ /_/ /_/\\__,_/ |___/\\___/ \\__,_/ |__/|__/_/_/ /_/_/ /_/\\___/_/ (_|_) \s 245  \s 246  """); 247  248  System.out.println("The winner is/are:"); 249  //print winners 250  winners.forEach(System.out::println); 251  } 252  253 }