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 }