Merge pull request #92 from rubenpirreram/server-resilance

server-resilance
This commit is contained in:
rubenpirreram
2026-05-10 17:16:08 +02:00
committed by GitHub
2 changed files with 130 additions and 44 deletions
@@ -88,12 +88,13 @@ public class TCPServer {
continue; continue;
} }
if (playerList.isEmpty()) { if (playerList.isEmpty()) {
if(controller.getModel() == null){
Game model = new Game(eventAddPlayer.getProposedNPlayer()); Game model = new Game(eventAddPlayer.getProposedNPlayer());
controller.setModel(model); controller.setModel(model);
playerList.setLimit(eventAddPlayer.getProposedNPlayer()); playerList.setLimit(eventAddPlayer.getProposedNPlayer());
} }
}
String username = eventAddPlayer.getUsername(); String username = eventAddPlayer.getUsername();
@@ -114,7 +115,8 @@ public class TCPServer {
// metti in attesa del socket heartbeat // metti in attesa del socket heartbeat
} else if (playerList.containsKey(username) && !playerList.get(username)) { }
else if(playerList.containsKey(username) && !playerList.get(username)){
// riconnessione // riconnessione
playerList.put(username, true); playerList.put(username, true);
System.out.println("Reconnected player: " + username); System.out.println("Reconnected player: " + username);
@@ -131,14 +133,16 @@ public class TCPServer {
clientHandlers.add(handler); clientHandlers.add(handler);
connectedPlayers++; connectedPlayers++;
actionQueue.add(new ReconnectPlayer(username)); actionQueue.add(new ReconnectPlayer(username));
} else { }
else{
clientSocket.getOutputStream().write(-1); clientSocket.getOutputStream().write(-1);
clientSocket.close(); clientSocket.close();
System.out.println("Player could not be added. Connection terminated."); System.out.println("Player could not be added. Connection terminated.");
} }
} catch (IOException | ClassNotFoundException e) { }
catch(IOException | ClassNotFoundException e){
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -3,6 +3,7 @@ package it.polimi.ingsw.gc14;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import it.polimi.ingsw.gc14.Model.Player; import it.polimi.ingsw.gc14.Model.Player;
import it.polimi.ingsw.gc14.Network.ClientPlayer; import it.polimi.ingsw.gc14.Network.ClientPlayer;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
@@ -11,6 +12,10 @@ import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer;
import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer; import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer;
import it.polimi.ingsw.gc14.View.TUI.TUI; import it.polimi.ingsw.gc14.View.TUI.TUI;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.util.*; import java.util.*;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
@@ -74,6 +79,7 @@ public class ServerLauncher {
this.actionQueue = actionQueue; this.actionQueue = actionQueue;
this.serverRMI = serverRMI; this.serverRMI = serverRMI;
this.gameController = gameController; this.gameController = gameController;
this.gameController.setModel(loadSave());
this.serverTCP = serverTCP; this.serverTCP = serverTCP;
} }
@@ -87,11 +93,20 @@ public class ServerLauncher {
* @throws RemoteException if an RMI error occurs * @throws RemoteException if an RMI error occurs
*/ */
public boolean doFirstEvent() throws InterruptedException, RemoteException { public boolean doFirstEvent() throws InterruptedException, RemoteException {
synchronized (gameController) { synchronized(gameController){
NetworkEvent event = actionQueue.take(); NetworkEvent event = actionQueue.take();
event.setIsError(!event.apply(gameController)); event.setIsError(!event.apply(gameController));
serverRMI.notifyAll(event); serverRMI.notifyAll(event);
serverTCP.notifyAll(event); serverTCP.notifyAll(event);
if(!event.getIsError()){
if(this.gameController.getModel().getCurrentState().getGameStage() == GameStages.ENDED){
this.deleteSave();
}
else if(!this.gameSave() ){
System.out.println("\n!!! Save failed !!!\n");
}
}
if (!playerList.get(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())) { if (!playerList.get(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())) {
actionQueue.offer(new SkipPlayerDisconnected(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())); actionQueue.offer(new SkipPlayerDisconnected(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName()));
} }
@@ -114,6 +129,7 @@ public class ServerLauncher {
BlockingQueue<NetworkEvent> actionQueue = new LinkedBlockingQueue<>(); BlockingQueue<NetworkEvent> actionQueue = new LinkedBlockingQueue<>();
GameController gameController = new GameController(); GameController gameController = new GameController();
String IP; String IP;
try { try {
IP=chooseNetworkInterface(new Scanner(System.in)); IP=chooseNetworkInterface(new Scanner(System.in));
} catch (Exception e) { } catch (Exception e) {
@@ -158,17 +174,20 @@ public class ServerLauncher {
// Game execution // Game execution
while (true) { while (true) {
try { try{
this.doFirstEvent(); this.doFirstEvent();
this.view.fullRender(); this.view.fullRender();
} catch (InterruptedException e) { }
catch(InterruptedException e){
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
break; break;
} catch (RemoteException e) { }
catch(RemoteException e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
} }
public static String chooseNetworkInterface(Scanner scanner) throws Exception { public static String chooseNetworkInterface(Scanner scanner) throws Exception {
List<String> ips = new ArrayList<>(); List<String> ips = new ArrayList<>();
@@ -201,4 +220,67 @@ public class ServerLauncher {
int choice = Integer.parseInt(scanner.nextLine().trim()); int choice = Integer.parseInt(scanner.nextLine().trim());
return ips.get(choice); return ips.get(choice);
} }
private boolean gameSave(){
try{
Path jarPath = Paths.get(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
Path filePath = jarPath.resolve("GameSaves/save.dat");
Files.createDirectories(filePath.getParent());
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()))){
oos.writeObject(this.gameController.getModel());
System.out.println("Game saved to: " + filePath.toAbsolutePath());
return true;
}
catch(IOException e){
e.printStackTrace();
return false;
}
}
catch(IOException e){
System.out.println("Couldn't create directory.");
e.printStackTrace();
return false;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private Game loadSave(){
try {
Path jarPath = Paths.get(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
Path filePath = jarPath.resolve("GameSaves/save.dat");
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath.toFile()))){
return (Game)(ois.readObject());
}
catch(FileNotFoundException e){
return null;
}
catch(IOException e){
e.printStackTrace();
return null;
}
catch(ClassNotFoundException e){
throw new RuntimeException(e);
}
}
catch(URISyntaxException e){
throw new RuntimeException(e);
}
}
private boolean deleteSave(){
try{
Path jarPath = Paths.get(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
Path filePath = jarPath.resolve("GameSaves/save.dat");
Files.delete(filePath);
return true;
}
catch(URISyntaxException e){
return false;
}
catch (IOException e){
return false;
}
}
} }