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 }