Merge branch 'main' of github.com:rubenpirreram/ing-sw-2026-pirrera-radice-pagani-pellegrino into error-logic-change
This commit is contained in:
@@ -8,7 +8,6 @@ import javafx.stage.Stage;
|
|||||||
public class ClientLauncherGUI {
|
public class ClientLauncherGUI {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("glass.win.uiScale", "1.0");
|
|
||||||
Application.launch(GUIApp.class, args);
|
Application.launch(GUIApp.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package it.polimi.ingsw.gc14;
|
package it.polimi.ingsw.gc14;
|
||||||
import it.polimi.ingsw.gc14.Controller.ClientController;
|
import it.polimi.ingsw.gc14.Controller.ClientController;
|
||||||
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
|
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
|
||||||
import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
|
import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
|
||||||
@@ -38,6 +39,7 @@ public class ClientLauncherTUI {
|
|||||||
*/
|
*/
|
||||||
public void main() throws InterruptedException {
|
public void main() throws InterruptedException {
|
||||||
view = new TUI(null);
|
view = new TUI(null);
|
||||||
|
admissibleChar.add("0");
|
||||||
admissibleChar.add("1");
|
admissibleChar.add("1");
|
||||||
admissibleChar.add("2");
|
admissibleChar.add("2");
|
||||||
admissibleChar.add("3");
|
admissibleChar.add("3");
|
||||||
@@ -57,6 +59,7 @@ public class ClientLauncherTUI {
|
|||||||
System.out.println("Insert username: ");
|
System.out.println("Insert username: ");
|
||||||
String username = scanner.next();
|
String username = scanner.next();
|
||||||
view.setUsername(username);
|
view.setUsername(username);
|
||||||
|
controller.setMyUsername(username);
|
||||||
System.out.println("Insert preferred number of players: ");
|
System.out.println("Insert preferred number of players: ");
|
||||||
int proposedNumPlayers = scanner.nextInt();
|
int proposedNumPlayers = scanner.nextInt();
|
||||||
System.out.println("Select RMI[0] o TCP[1]: ");
|
System.out.println("Select RMI[0] o TCP[1]: ");
|
||||||
@@ -137,7 +140,16 @@ public class ClientLauncherTUI {
|
|||||||
|
|
||||||
if(admissibleChar.contains(action))
|
if(admissibleChar.contains(action))
|
||||||
{
|
{
|
||||||
if (!action.equals("6") && !action.equals("A") && !action.equals("B") && !action.equals("C")&&!action.equals("a") && !action.equals("b") && !action.equals("c")) {
|
if(action.equals("0"))
|
||||||
|
{
|
||||||
|
System.out.println("Are you sure? Y/N");
|
||||||
|
String c= scanner.next();
|
||||||
|
if(!c.equals("Y") && !c.equals("y"))
|
||||||
|
{
|
||||||
|
view.render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}else if (!action.equals("6") && !action.equals("A") && !action.equals("B") && !action.equals("C")&&!action.equals("a") && !action.equals("b") && !action.equals("c")) {
|
||||||
try {
|
try {
|
||||||
System.out.println("Insert the required position:");
|
System.out.println("Insert the required position:");
|
||||||
pos = scanner.nextInt();
|
pos = scanner.nextInt();
|
||||||
@@ -147,13 +159,17 @@ public class ClientLauncherTUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "1" -> controller.slotChoice(username, pos);
|
case "0" -> {
|
||||||
case "2" -> controller.drawUpperTribeCard(username, pos);
|
controller.disconnect();
|
||||||
case "3" -> controller.drawUpperBuildingCard(username, pos);
|
System.exit(0);
|
||||||
case "4" -> controller.drawLowerTribeCard(username, pos);
|
}
|
||||||
case "5" -> controller.drawLowerBuildingCard(username, pos);
|
case "1" -> controller.slotChoice(pos);
|
||||||
case "6" -> controller.skipTurn(username);
|
case "2" -> controller.drawUpperTribeCard(pos);
|
||||||
case "7" -> controller.totemChoice(username,pos);
|
case "3" -> controller.drawUpperBuildingCard(pos);
|
||||||
|
case "4" -> controller.drawLowerTribeCard(pos);
|
||||||
|
case "5" -> controller.drawLowerBuildingCard(pos);
|
||||||
|
case "6" -> controller.skipTurn();
|
||||||
|
case "7" -> controller.totemChoice(pos);
|
||||||
case "A", "a" -> view.fullRender();
|
case "A", "a" -> view.fullRender();
|
||||||
case "B", "b" -> view.renderBoard();
|
case "B", "b" -> view.renderBoard();
|
||||||
case "C", "c" -> view.renderPlayer();
|
case "C", "c" -> view.renderPlayer();
|
||||||
|
|||||||
@@ -83,15 +83,11 @@ public class ClientController {
|
|||||||
* <p>If the specified player is not the current player, an error message
|
* <p>If the specified player is not the current player, an error message
|
||||||
* is shown. Otherwise, the request is forwarded to the network client.
|
* is shown. Otherwise, the request is forwarded to the network client.
|
||||||
*
|
*
|
||||||
* @param playerUsername the username of the player performing the action.
|
|
||||||
* @param pos the index of the card to draw.
|
* @param pos the index of the card to draw.
|
||||||
*/
|
*/
|
||||||
public void drawUpperTribeCard(String playerUsername, int pos) {
|
public void drawUpperTribeCard(int pos) {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.drawUpperTribeCard(myUsername, pos);
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
|
||||||
client.drawUpperTribeCard(playerUsername, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,15 +96,11 @@ public class ClientController {
|
|||||||
* <p>If the specified player is not the current player, an error message
|
* <p>If the specified player is not the current player, an error message
|
||||||
* is shown. Otherwise, the request is forwarded to the network client.
|
* is shown. Otherwise, the request is forwarded to the network client.
|
||||||
*
|
*
|
||||||
* @param playerUsername the username of the player performing the action.
|
|
||||||
* @param pos the index of the card to draw.
|
* @param pos the index of the card to draw.
|
||||||
*/
|
*/
|
||||||
public void drawLowerTribeCard(String playerUsername, int pos) {
|
public void drawLowerTribeCard(int pos) {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.drawLowerTribeCard(myUsername, pos);
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
|
||||||
client.drawLowerTribeCard(playerUsername, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,15 +109,11 @@ public class ClientController {
|
|||||||
* <p>If the specified player is not the current player, an error message
|
* <p>If the specified player is not the current player, an error message
|
||||||
* is shown. Otherwise, the request is forwarded to the network client.
|
* is shown. Otherwise, the request is forwarded to the network client.
|
||||||
*
|
*
|
||||||
* @param playerUsername the username of the player performing the action.
|
|
||||||
* @param pos the index of the card to draw.
|
* @param pos the index of the card to draw.
|
||||||
*/
|
*/
|
||||||
public void drawUpperBuildingCard(String playerUsername, int pos) {
|
public void drawUpperBuildingCard(int pos) {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.drawUpperBuildingCard(myUsername, pos);
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
|
||||||
client.drawUpperBuildingCard(playerUsername, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,15 +122,10 @@ public class ClientController {
|
|||||||
* <p>If the specified player is not the current player, an error message
|
* <p>If the specified player is not the current player, an error message
|
||||||
* is shown. Otherwise, the request is forwarded to the network client.
|
* is shown. Otherwise, the request is forwarded to the network client.
|
||||||
*
|
*
|
||||||
* @param playerUsername the username of the player performing the action.
|
|
||||||
* @param pos the index of the card to draw.
|
* @param pos the index of the card to draw.
|
||||||
*/
|
*/
|
||||||
public void drawLowerBuildingCard(String playerUsername, int pos) {
|
public void drawLowerBuildingCard(int pos) {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.drawLowerBuildingCard(myUsername, pos);
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
|
||||||
client.drawLowerBuildingCard(playerUsername, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,15 +133,9 @@ public class ClientController {
|
|||||||
*
|
*
|
||||||
* <p>If the specified player is not the current player, an error message
|
* <p>If the specified player is not the current player, an error message
|
||||||
* is shown. Otherwise, the request is forwarded to the network client.
|
* is shown. Otherwise, the request is forwarded to the network client.
|
||||||
*
|
|
||||||
* @param playerUsername the username of the player performing the action.
|
|
||||||
*/
|
*/
|
||||||
public void skipTurn(String playerUsername) {
|
public void skipTurn() {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.skipTurn(myUsername);
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
|
||||||
client.skipTurn(playerUsername);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,15 +144,10 @@ public class ClientController {
|
|||||||
* <p>If the specified player is not the current player, an error message
|
* <p>If the specified player is not the current player, an error message
|
||||||
* is shown. Otherwise, the request is forwarded to the network client.
|
* is shown. Otherwise, the request is forwarded to the network client.
|
||||||
*
|
*
|
||||||
* @param playerUsername the username of the player performing the action.
|
|
||||||
* @param pos the index of the selected slot.
|
* @param pos the index of the selected slot.
|
||||||
*/
|
*/
|
||||||
public void slotChoice(String playerUsername, int pos) {
|
public void slotChoice(int pos) {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.slotChoice(myUsername, pos);
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
|
||||||
client.slotChoice(playerUsername, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,14 +157,15 @@ public class ClientController {
|
|||||||
* is shown. Otherwise, the selected totem is retrieved from the available
|
* is shown. Otherwise, the selected totem is retrieved from the available
|
||||||
* totems list and the choice is forwarded to the network client.
|
* totems list and the choice is forwarded to the network client.
|
||||||
*
|
*
|
||||||
* @param playerUsername the username of the player making the choice.
|
|
||||||
* @param pos the index of the selected totem in the available totems list.
|
* @param pos the index of the selected totem in the available totems list.
|
||||||
*/
|
*/
|
||||||
public void totemChoice(String playerUsername, int pos) {
|
public void totemChoice(int pos) {
|
||||||
if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) {
|
client.totemChoice(myUsername, String.valueOf(miniModel.availableTotems.get(pos)));
|
||||||
view.showError("It's not your turn!");
|
|
||||||
} else {
|
}
|
||||||
client.totemChoice(playerUsername, String.valueOf(miniModel.availableTotems.get(pos)));
|
|
||||||
}
|
public void disconnect()
|
||||||
|
{
|
||||||
|
client.notifyDisconnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,4 +70,7 @@ public interface IClient {
|
|||||||
* @param totem the name of the selected totem.
|
* @param totem the name of the selected totem.
|
||||||
*/
|
*/
|
||||||
void totemChoice(String playerUsername, String totem);
|
void totemChoice(String playerUsername, String totem);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
void notifyDisconnection();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class RMIClient implements IClient {
|
|||||||
future.get(PING_TIMEOUT_MS, TimeUnit.MILLISECONDS); // mirrors setSoTimeout(5000)
|
future.get(PING_TIMEOUT_MS, TimeUnit.MILLISECONDS); // mirrors setSoTimeout(5000)
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
System.out.println("RMI ping timeout: " + username);
|
//error sending
|
||||||
disconnect();
|
disconnect();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
disconnect();
|
disconnect();
|
||||||
@@ -124,7 +124,7 @@ public class RMIClient implements IClient {
|
|||||||
if (!running) return;
|
if (!running) return;
|
||||||
running = false;
|
running = false;
|
||||||
if (pingSender != null) pingSender.shutdownNow();
|
if (pingSender != null) pingSender.shutdownNow();
|
||||||
controller.view.showError("Connessione al server persa");
|
controller.view.showError("Connection with server closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -235,5 +235,15 @@ public class RMIClient implements IClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyDisconnection() {
|
||||||
|
pingSender.shutdownNow();
|
||||||
|
try{
|
||||||
|
stub.disconnectPlayer(username);
|
||||||
|
}
|
||||||
|
catch (RemoteException e){
|
||||||
|
System.out.println("Error during remote disconnection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -93,4 +93,6 @@ public interface IGameServer extends Remote {
|
|||||||
* @throws RemoteException if an RMI communication error occurs.
|
* @throws RemoteException if an RMI communication error occurs.
|
||||||
*/
|
*/
|
||||||
void ping(String username) throws RemoteException;
|
void ping(String username) throws RemoteException;
|
||||||
|
|
||||||
|
void disconnectPlayer(String username) throws RemoteException;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ public class RMIHeartbeat {
|
|||||||
* the associated RMI callback is removed, and a disconnection event is
|
* the associated RMI callback is removed, and a disconnection event is
|
||||||
* added to the action queue for server-side processing.
|
* added to the action queue for server-side processing.
|
||||||
*/
|
*/
|
||||||
private void disconnect() {
|
public void disconnect() {
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
running = false;
|
running = false;
|
||||||
watchdog.shutdownNow();
|
watchdog.shutdownNow();
|
||||||
|
|||||||
@@ -47,16 +47,6 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
|||||||
BlockingQueue<NetworkEvent> actionQueue;
|
BlockingQueue<NetworkEvent> actionQueue;
|
||||||
private LimitedMap<String, Boolean> playerList;
|
private LimitedMap<String, Boolean> playerList;
|
||||||
|
|
||||||
private boolean serverCrashed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether the server is recovering from a previous crash.
|
|
||||||
*
|
|
||||||
* @param serverCrashed {@code true} if the server is in crash-recovery mode,
|
|
||||||
*/
|
|
||||||
public void setServerCrashed(boolean serverCrashed) {
|
|
||||||
this.serverCrashed = serverCrashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an RMI server with the required game and network components.
|
* Constructs an RMI server with the required game and network components.
|
||||||
@@ -96,30 +86,25 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
|||||||
if (preferredInt < 2 || preferredInt > 5) return false;
|
if (preferredInt < 2 || preferredInt > 5) return false;
|
||||||
|
|
||||||
synchronized (controller) {
|
synchronized (controller) {
|
||||||
if(serverCrashed)
|
|
||||||
{
|
if (playerList.isEmpty() && controller.getModel()==null) {
|
||||||
if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)) {
|
controller.setModel(new Game(preferredInt));
|
||||||
clients.put(username, callback);
|
playerList.setLimit(preferredInt);
|
||||||
playerList.put(username, true);
|
System.out.println("Game Created With :"+preferredInt+" Players");
|
||||||
startWatchdog(username);
|
|
||||||
System.out.println("(After crash)Reconnected player: " + username);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
if (controller.addPlayer(username)) {
|
||||||
{
|
clients.put(username, callback);
|
||||||
if (playerList.isEmpty()) {
|
playerList.put(username, true);
|
||||||
controller.setModel(new Game(preferredInt));
|
startWatchdog(username);
|
||||||
playerList.setLimit(preferredInt);
|
System.out.println("Accepted player: " + username);
|
||||||
System.out.println("Game Created With :"+preferredInt+" Players");
|
return true;
|
||||||
}
|
}
|
||||||
if (controller.addPlayer(username)) {
|
if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)) {
|
||||||
clients.put(username, callback);
|
clients.put(username, callback);
|
||||||
playerList.put(username, true);
|
playerList.put(username, true);
|
||||||
startWatchdog(username);
|
startWatchdog(username);
|
||||||
System.out.println("Accepted player: " + username);
|
System.out.println("(After crash)Reconnected player: " + username);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (playerList.containsKey(username) && !playerList.get(username)) {
|
if (playerList.containsKey(username) && !playerList.get(username)) {
|
||||||
playerList.put(username, true);
|
playerList.put(username, true);
|
||||||
@@ -279,13 +264,10 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
|||||||
* on the specified port, and registers this server instance under the
|
* on the specified port, and registers this server instance under the
|
||||||
* {@code RMIGameServer} name.
|
* {@code RMIGameServer} name.
|
||||||
*
|
*
|
||||||
* @param serverCrashed {@code true} if the server is being restarted after a crash,
|
|
||||||
* {@code false} otherwise.
|
|
||||||
* @return {@code true} if the server starts successfully,
|
* @return {@code true} if the server starts successfully,
|
||||||
* {@code false} otherwise.
|
* {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean start(boolean serverCrashed) {
|
public boolean start() {
|
||||||
this.serverCrashed = serverCrashed;
|
|
||||||
try {
|
try {
|
||||||
System.setProperty("java.rmi.server.hostname", host);
|
System.setProperty("java.rmi.server.hostname", host);
|
||||||
registry = LocateRegistry.createRegistry(nPort);
|
registry = LocateRegistry.createRegistry(nPort);
|
||||||
@@ -332,6 +314,10 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
|||||||
watchdogs.put(username, wd);
|
watchdogs.put(username, wd);
|
||||||
wd.start();
|
wd.start();
|
||||||
}
|
}
|
||||||
|
public void disconnectPlayer(String username) {
|
||||||
|
RMIHeartbeat wd = watchdogs.get(username);
|
||||||
|
wd.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -107,8 +107,12 @@ public class TCPClient implements IClient {
|
|||||||
ScheduledExecutorService sender = Executors.newSingleThreadScheduledExecutor();
|
ScheduledExecutorService sender = Executors.newSingleThreadScheduledExecutor();
|
||||||
sender.scheduleAtFixedRate(() -> {
|
sender.scheduleAtFixedRate(() -> {
|
||||||
try {
|
try {
|
||||||
heartbeatOut.write(PING);
|
synchronized (heartbeatOut)
|
||||||
heartbeatOut.flush();
|
{
|
||||||
|
heartbeatOut.write(PING);
|
||||||
|
heartbeatOut.flush();
|
||||||
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
sender.shutdownNow();
|
sender.shutdownNow();
|
||||||
disconnect();
|
disconnect();
|
||||||
@@ -263,4 +267,17 @@ public class TCPClient implements IClient {
|
|||||||
public void totemChoice(String playerUsername,String totems) {
|
public void totemChoice(String playerUsername,String totems) {
|
||||||
doEvent(new TotemChoice(playerUsername,totems));
|
doEvent(new TotemChoice(playerUsername,totems));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyDisconnection()
|
||||||
|
{
|
||||||
|
synchronized (heartbeatOut)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
heartbeatOut.write(-1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -94,10 +94,9 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
clientHandlers.remove(this);
|
System.err.println("Error in incoming connection/disconnection");
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new RuntimeException(e);
|
System.err.println("Class not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,13 @@ public class HeartbeatHandler implements Runnable {
|
|||||||
try {
|
try {
|
||||||
while (running) {
|
while (running) {
|
||||||
int b = in.read(); // blocca finché non arriva un byte
|
int b = in.read(); // blocca finché non arriva un byte
|
||||||
if (b == -1) { disconnect(); break; } // stream chiusa
|
if (b == -1) {
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
out.write(-1);
|
||||||
|
}
|
||||||
|
disconnect(); break;
|
||||||
|
} // stream chiusa
|
||||||
if (b == PING) {
|
if (b == PING) {
|
||||||
lastReceivedTime = System.currentTimeMillis();
|
lastReceivedTime = System.currentTimeMillis();
|
||||||
out.write(PONG);
|
out.write(PONG);
|
||||||
@@ -127,7 +133,7 @@ public class HeartbeatHandler implements Runnable {
|
|||||||
* <p>The handler is stopped, the watchdog task is terminated, the main
|
* <p>The handler is stopped, the watchdog task is terminated, the main
|
||||||
* {@link ClientHandler} is disconnected, and the heartbeat socket is closed.
|
* {@link ClientHandler} is disconnected, and the heartbeat socket is closed.
|
||||||
*/
|
*/
|
||||||
private void disconnect() {
|
private synchronized void disconnect() {
|
||||||
running = false;
|
running = false;
|
||||||
watchdog.shutdownNow();
|
watchdog.shutdownNow();
|
||||||
mainHandler.disconnect(); // disconnette anche il socket principale
|
mainHandler.disconnect(); // disconnette anche il socket principale
|
||||||
|
|||||||
@@ -73,20 +73,6 @@ public class TCPServer {
|
|||||||
*/
|
*/
|
||||||
List<ClientHandler> clientHandlers;
|
List<ClientHandler> clientHandlers;
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag indicating whether the server is recovering from a previous crash.
|
|
||||||
*/
|
|
||||||
boolean serverCrashed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether the server is recovering from a previous crash.
|
|
||||||
*
|
|
||||||
* @param serverCrashed {@code true} if the server is in crash-recovery mode,
|
|
||||||
* {@code false} otherwise.
|
|
||||||
*/
|
|
||||||
public void setServerCrashed(boolean serverCrashed) {
|
|
||||||
this.serverCrashed = serverCrashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary map associating each username with the corresponding
|
* Temporary map associating each username with the corresponding
|
||||||
@@ -129,12 +115,8 @@ public class TCPServer {
|
|||||||
* the connection is handled either as a new player joining the game
|
* the connection is handled either as a new player joining the game
|
||||||
* or as a reconnection attempt.
|
* or as a reconnection attempt.
|
||||||
*
|
*
|
||||||
* @param serverCrashed {@code true} if the server is being restarted after a crash,
|
|
||||||
* {@code false} otherwise.
|
|
||||||
*/
|
*/
|
||||||
public void start(boolean serverCrashed) {
|
public void start() {
|
||||||
this.serverCrashed = serverCrashed;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
socketTCP = new ServerSocket(port);
|
socketTCP = new ServerSocket(port);
|
||||||
heartbeatSocketTCP = new ServerSocket(heartbeatPort);
|
heartbeatSocketTCP = new ServerSocket(heartbeatPort);
|
||||||
@@ -180,70 +162,64 @@ public class TCPServer {
|
|||||||
synchronized (controller) {
|
synchronized (controller) {
|
||||||
String username = eventAddPlayer.getUsername();
|
String username = eventAddPlayer.getUsername();
|
||||||
//reconnect players after a server crash
|
//reconnect players after a server crash
|
||||||
if (serverCrashed) {
|
if (playerList.isEmpty()&& controller.getModel()==null) {
|
||||||
if (controller.getModel().getPlayers().stream()
|
Game model = new Game(eventAddPlayer.getProposedNPlayer());
|
||||||
.anyMatch(p -> p.getUserName().equals(username))
|
controller.setModel(model);
|
||||||
&& !playerList.containsKey(username)) {
|
playerList.setLimit(eventAddPlayer.getProposedNPlayer());
|
||||||
playerList.put(username, true);
|
System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players");
|
||||||
System.out.println("(After crash)Reconnected player: " + username);
|
}
|
||||||
|
|
||||||
ClientHandler handler = new ClientHandler(
|
if (controller.addPlayer(username)) {
|
||||||
username,
|
playerList.put(username, true);
|
||||||
clientSocket,
|
System.out.println("Accepted player: " + username);
|
||||||
clientSend,
|
|
||||||
clientReceive,
|
|
||||||
clientHandlers,
|
|
||||||
playerList,
|
|
||||||
actionQueue
|
|
||||||
);
|
|
||||||
|
|
||||||
clientSocket.getOutputStream().write(1);
|
ClientHandler handler = new ClientHandler(
|
||||||
pendingHeartbeat.put(username, handler);
|
username,
|
||||||
|
clientSocket,
|
||||||
|
clientSend,
|
||||||
|
clientReceive,
|
||||||
|
clientHandlers,
|
||||||
|
playerList,
|
||||||
|
actionQueue
|
||||||
|
);
|
||||||
|
|
||||||
Thread thread = new Thread(handler);
|
clientSocket.getOutputStream().write(1);
|
||||||
thread.start();
|
pendingHeartbeat.put(username, handler);
|
||||||
|
|
||||||
clientHandlers.add(handler);
|
Thread thread = new Thread(handler);
|
||||||
connectedPlayers++;
|
thread.start();
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
clientHandlers.add(handler);
|
||||||
|
connectedPlayers++;
|
||||||
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
//manages a new player adding
|
if (controller.getModel().getPlayers().stream()
|
||||||
else {
|
.anyMatch(p -> p.getUserName().equals(username))
|
||||||
if (playerList.isEmpty()) {
|
&& !playerList.containsKey(username)) {
|
||||||
Game model = new Game(eventAddPlayer.getProposedNPlayer());
|
playerList.put(username, true);
|
||||||
controller.setModel(model);
|
System.out.println("(After crash)Reconnected player: " + username);
|
||||||
playerList.setLimit(eventAddPlayer.getProposedNPlayer());
|
|
||||||
System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controller.addPlayer(username)) {
|
ClientHandler handler = new ClientHandler(
|
||||||
playerList.put(username, true);
|
username,
|
||||||
System.out.println("Accepted player: " + username);
|
clientSocket,
|
||||||
|
clientSend,
|
||||||
|
clientReceive,
|
||||||
|
clientHandlers,
|
||||||
|
playerList,
|
||||||
|
actionQueue
|
||||||
|
);
|
||||||
|
|
||||||
ClientHandler handler = new ClientHandler(
|
clientSocket.getOutputStream().write(1);
|
||||||
username,
|
pendingHeartbeat.put(username, handler);
|
||||||
clientSocket,
|
|
||||||
clientSend,
|
|
||||||
clientReceive,
|
|
||||||
clientHandlers,
|
|
||||||
playerList,
|
|
||||||
actionQueue
|
|
||||||
);
|
|
||||||
|
|
||||||
clientSocket.getOutputStream().write(1);
|
Thread thread = new Thread(handler);
|
||||||
pendingHeartbeat.put(username, handler);
|
thread.start();
|
||||||
|
|
||||||
Thread thread = new Thread(handler);
|
clientHandlers.add(handler);
|
||||||
thread.start();
|
connectedPlayers++;
|
||||||
|
continue;
|
||||||
|
|
||||||
clientHandlers.add(handler);
|
|
||||||
connectedPlayers++;
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//reconnect a previously disconnected player
|
//reconnect a previously disconnected player
|
||||||
if (playerList.containsKey(username)
|
if (playerList.containsKey(username)
|
||||||
@@ -288,8 +264,6 @@ public class TCPServer {
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,8 +186,6 @@ public class ServerLauncher {
|
|||||||
if(!entry.getValue())
|
if(!entry.getValue())
|
||||||
playerList.remove(entry.getKey());
|
playerList.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
serverRMI.setServerCrashed(false);
|
|
||||||
serverTCP.setServerCrashed(false);
|
|
||||||
}
|
}
|
||||||
//notify the event
|
//notify the event
|
||||||
else {
|
else {
|
||||||
@@ -195,6 +193,10 @@ public class ServerLauncher {
|
|||||||
serverTCP.notifyAll(event);
|
serverTCP.notifyAll(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
serverRMI.notifyAll(event);
|
||||||
|
serverTCP.notifyAll(event);
|
||||||
|
}
|
||||||
return !event.getIsError();
|
return !event.getIsError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,13 +204,15 @@ public class ServerLauncher {
|
|||||||
// removes disconneted players when the game is ended
|
// removes disconneted players when the game is ended
|
||||||
if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER))
|
if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER))
|
||||||
{
|
{
|
||||||
playerList.remove(event.getUsername());
|
synchronized (gameController) {
|
||||||
if(playerList.isEmpty())
|
playerList.remove(event.getUsername());
|
||||||
{
|
if (playerList.isEmpty()) {
|
||||||
gameController.setModel(null);
|
|
||||||
System.out.println("\n!!! Player list is now empty, ready for a new game init !!!\n");
|
gameController.setModel(null);
|
||||||
|
System.out.println("\n!!! Player list is now empty, ready for a new game init !!!\n");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -241,7 +245,6 @@ 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;
|
||||||
boolean serverCrashed;
|
|
||||||
try {
|
try {
|
||||||
IP=chooseNetworkInterface(new Scanner(System.in));
|
IP=chooseNetworkInterface(new Scanner(System.in));
|
||||||
System.out.println(IP);
|
System.out.println(IP);
|
||||||
@@ -262,10 +265,6 @@ public class ServerLauncher {
|
|||||||
playerList.put(entry.getKey().getUserName(),false);
|
playerList.put(entry.getKey().getUserName(),false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serverCrashed = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
serverCrashed = false;
|
|
||||||
}
|
}
|
||||||
playerList.setAction(()->{
|
playerList.setAction(()->{
|
||||||
new Thread(()->{
|
new Thread(()->{
|
||||||
@@ -277,8 +276,6 @@ public class ServerLauncher {
|
|||||||
}
|
}
|
||||||
serverRMI.notifyAll(miniModel);
|
serverRMI.notifyAll(miniModel);
|
||||||
serverTCP.notifyAll(miniModel);
|
serverTCP.notifyAll(miniModel);
|
||||||
view = new TUI(miniModel);
|
|
||||||
view.render();
|
|
||||||
}).start();
|
}).start();
|
||||||
});
|
});
|
||||||
new Thread(()-> {
|
new Thread(()-> {
|
||||||
@@ -291,8 +288,8 @@ public class ServerLauncher {
|
|||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
serverRMI.start(serverCrashed);
|
serverRMI.start();
|
||||||
new Thread(()->{serverTCP.start(serverCrashed);}).start();
|
new Thread(()->{serverTCP.start();}).start();
|
||||||
System.out.println("Server RMI: "+System.getProperty("java.rmi.server.hostname"));
|
System.out.println("Server RMI: "+System.getProperty("java.rmi.server.hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,10 +307,6 @@ public class ServerLauncher {
|
|||||||
while (true) {
|
while (true) {
|
||||||
try{
|
try{
|
||||||
this.doFirstEvent();
|
this.doFirstEvent();
|
||||||
// if(view!=null)
|
|
||||||
// {
|
|
||||||
// view.fullRender();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
catch(InterruptedException e){
|
catch(InterruptedException e){
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import javafx.application.Platform;
|
|||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.geometry.Rectangle2D;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Screen;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
@@ -62,23 +64,28 @@ public class GUI extends Application implements IView {
|
|||||||
|
|
||||||
|
|
||||||
loaderMain = new FXMLLoader(getClass().getResource("/GUIScene/main.fxml"));
|
loaderMain = new FXMLLoader(getClass().getResource("/GUIScene/main.fxml"));
|
||||||
loaderMain.setControllerFactory(clazz -> {
|
mainScene = new Scene(loaderMain.load());
|
||||||
MainFXMLController controllerMain = new MainFXMLController();
|
controllerMain = loaderMain.getController();
|
||||||
controllerMain.setController(controller);
|
controllerMain.setController(controller);
|
||||||
return controllerMain;
|
|
||||||
});
|
|
||||||
|
|
||||||
loaderLeaderboard = new FXMLLoader(getClass().getResource("/GUIScene/standing.fxml"));
|
loaderLeaderboard = new FXMLLoader(getClass().getResource("/GUIScene/standing.fxml"));
|
||||||
leaderboardScene = new Scene(loaderLeaderboard.load());
|
leaderboardScene = new Scene(loaderLeaderboard.load());
|
||||||
controllerLeaderboard = loaderLeaderboard.getController();
|
controllerLeaderboard = loaderLeaderboard.getController();
|
||||||
controllerLeaderboard.setController(controller,primaryStage,loginScene);
|
controllerLeaderboard.setController(controller,primaryStage,loginScene);
|
||||||
|
|
||||||
mainScene = new Scene(loaderMain.load());
|
|
||||||
controllerMain = loaderMain.getController();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
showLogin();
|
|
||||||
|
primaryStage.setScene(loginScene);
|
||||||
|
primaryStage.setFullScreen(true);
|
||||||
|
Rectangle2D tmp = Screen.getPrimary().getVisualBounds();
|
||||||
|
primaryStage.setWidth(tmp.getWidth());
|
||||||
|
primaryStage.setHeight(tmp.getHeight());
|
||||||
|
primaryStage.setX(tmp.getMinX());
|
||||||
|
primaryStage.setY(tmp.getMinY());
|
||||||
|
primaryStage.setResizable(false);
|
||||||
|
|
||||||
primaryStage.setTitle("Mesos");
|
primaryStage.setTitle("Mesos");
|
||||||
primaryStage.setOnCloseRequest(e -> {
|
primaryStage.setOnCloseRequest(e -> {
|
||||||
Platform.exit();
|
Platform.exit();
|
||||||
@@ -87,10 +94,6 @@ public class GUI extends Application implements IView {
|
|||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showLogin() throws IOException {
|
|
||||||
primaryStage.setScene(loginScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setModel(MiniModel miniModel) {
|
public void setModel(MiniModel miniModel) {
|
||||||
@@ -103,24 +106,34 @@ public class GUI extends Application implements IView {
|
|||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
|
boolean toFull=false;
|
||||||
|
|
||||||
synchronized (miniModel) {
|
synchronized (miniModel) {
|
||||||
if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) {
|
if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) {
|
||||||
primaryStage.setScene(totemScene);
|
if (primaryStage.getScene()!=leaderboardScene) {
|
||||||
|
toFull=true;
|
||||||
|
}
|
||||||
controllerTotem.render();
|
controllerTotem.render();
|
||||||
|
primaryStage.setScene(totemScene);
|
||||||
} else if (controller.miniModel.currentState.getGameStage() == ENDED) {
|
} else if (controller.miniModel.currentState.getGameStage() == ENDED) {
|
||||||
primaryStage.setScene(leaderboardScene);
|
if (primaryStage.getScene()!=leaderboardScene) {
|
||||||
|
toFull=true;
|
||||||
|
}
|
||||||
controllerLeaderboard.render();
|
controllerLeaderboard.render();
|
||||||
|
primaryStage.setScene(leaderboardScene);
|
||||||
} else {
|
} else {
|
||||||
double w = primaryStage.getWidth();
|
if (primaryStage.getScene()!=mainScene) {
|
||||||
double h = primaryStage.getHeight();
|
toFull=true;
|
||||||
|
}
|
||||||
|
//double w = primaryStage.getWidth();
|
||||||
|
//double h = primaryStage.getHeight();
|
||||||
primaryStage.setScene(mainScene);
|
primaryStage.setScene(mainScene);
|
||||||
primaryStage.setWidth(w);
|
|
||||||
primaryStage.setHeight(h);
|
|
||||||
primaryStage.setMinHeight(h);
|
|
||||||
primaryStage.setMinWidth(w);
|
|
||||||
primaryStage.setResizable(false);
|
|
||||||
controllerMain.render();
|
controllerMain.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (toFull) {
|
||||||
|
primaryStage.setFullScreen(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -136,6 +149,7 @@ public class GUI extends Application implements IView {
|
|||||||
synchronized (miniModel) {
|
synchronized (miniModel) {
|
||||||
controllerMain.isError = true;
|
controllerMain.isError = true;
|
||||||
controllerMain.render();
|
controllerMain.render();
|
||||||
|
System.out.println("ERRORE PORCODIDODODODOD");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,6 +362,7 @@ public class LeaderboardFXMLController {
|
|||||||
// ==== ACTIONS ====
|
// ==== ACTIONS ====
|
||||||
@FXML
|
@FXML
|
||||||
private void onNewGame() {
|
private void onNewGame() {
|
||||||
|
controller.disconnect();
|
||||||
primaryStage.setScene(loginScene);
|
primaryStage.setScene(loginScene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import java.util.*;
|
|||||||
|
|
||||||
public class MainFXMLController {
|
public class MainFXMLController {
|
||||||
|
|
||||||
|
@FXML private GridPane leftGrid;
|
||||||
@FXML private ScrollPane playerSide;
|
@FXML private ScrollPane playerSide;
|
||||||
@FXML private HBox mainHBox;
|
@FXML private HBox mainHBox;
|
||||||
@FXML private ImageView backgroundImage;
|
@FXML private ImageView backgroundImage;
|
||||||
@@ -75,6 +76,7 @@ public class MainFXMLController {
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14);
|
Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14);
|
||||||
|
|
||||||
|
|
||||||
popup = new Popup();
|
popup = new Popup();
|
||||||
mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {
|
mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {
|
||||||
if (newScene != null) {
|
if (newScene != null) {
|
||||||
@@ -102,11 +104,16 @@ public class MainFXMLController {
|
|||||||
|
|
||||||
// ==== RENDER ====
|
// ==== RENDER ====
|
||||||
public void render() {
|
public void render() {
|
||||||
renderUpper();
|
|
||||||
renderBoard();
|
if(!isError) {
|
||||||
renderLower();
|
renderUpper();
|
||||||
renderMyHand();
|
renderBoard();
|
||||||
|
renderLower();
|
||||||
|
renderMyHand();
|
||||||
|
}
|
||||||
renderSidePanel();
|
renderSidePanel();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -156,7 +163,7 @@ public class MainFXMLController {
|
|||||||
// ==== ELEMENTS ====
|
// ==== ELEMENTS ====
|
||||||
private StackPane createOrder(String num) {
|
private StackPane createOrder(String num) {
|
||||||
ImageView img = new ImageView(loadImage("/GUIImages/Orders/order-" + num + ".png"));
|
ImageView img = new ImageView(loadImage("/GUIImages/Orders/order-" + num + ".png"));
|
||||||
img.fitHeightProperty().bind(board.heightProperty().multiply(0.94));
|
img.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(40).divide(4).multiply(0.94));
|
||||||
img.setPreserveRatio(true);
|
img.setPreserveRatio(true);
|
||||||
addClip(img);
|
addClip(img);
|
||||||
return new StackPane(img);
|
return new StackPane(img);
|
||||||
@@ -165,7 +172,7 @@ public class MainFXMLController {
|
|||||||
private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) {
|
private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) {
|
||||||
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"));
|
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"));
|
||||||
img.setPreserveRatio(true);
|
img.setPreserveRatio(true);
|
||||||
img.fitHeightProperty().bind(board.heightProperty().multiply(0.94)); // TODO perchè è tutto moltiplicato per una costante ma in board facciamo -15?
|
img.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(40).divide(4).multiply(0.94));
|
||||||
addClip(img);
|
addClip(img);
|
||||||
StackPane wrapper = new StackPane(img);
|
StackPane wrapper = new StackPane(img);
|
||||||
|
|
||||||
@@ -175,7 +182,7 @@ public class MainFXMLController {
|
|||||||
totem.fitHeightProperty().bind(img.fitHeightProperty().multiply(0.332));
|
totem.fitHeightProperty().bind(img.fitHeightProperty().multiply(0.332));
|
||||||
totem.setPreserveRatio(true);
|
totem.setPreserveRatio(true);
|
||||||
StackPane.setAlignment(totem, Pos.TOP_LEFT);
|
StackPane.setAlignment(totem, Pos.TOP_LEFT);
|
||||||
StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight())); // TODO perchè margine sx incrementa con altezza e non larghezza?
|
StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight()));
|
||||||
wrapper.getChildren().add(totem);
|
wrapper.getChildren().add(totem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +194,7 @@ public class MainFXMLController {
|
|||||||
private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow, Region parent) {
|
private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow, Region parent) {
|
||||||
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
|
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
|
||||||
img.setPreserveRatio(true);
|
img.setPreserveRatio(true);
|
||||||
img.fitHeightProperty().bind(parent.heightProperty().multiply(0.90));
|
img.fitHeightProperty().bind(parent.getScene().heightProperty().subtract(40).divide(4).multiply(0.90));
|
||||||
addClip(img);
|
addClip(img);
|
||||||
StackPane wrapper = new StackPane(img);
|
StackPane wrapper = new StackPane(img);
|
||||||
if (withShadow) addShadow(wrapper);
|
if (withShadow) addShadow(wrapper);
|
||||||
@@ -207,7 +214,7 @@ public class MainFXMLController {
|
|||||||
for (TribeCard card : controller.miniModel.upperListTribeCards) {
|
for (TribeCard card : controller.miniModel.upperListTribeCards) {
|
||||||
final int index = i;
|
final int index = i;
|
||||||
StackPane img = createCard(card, true, true, upperList);
|
StackPane img = createCard(card, true, true, upperList);
|
||||||
img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index));
|
img.setOnMouseClicked(e -> controller.drawUpperTribeCard(index));
|
||||||
upperList.getChildren().add(img);
|
upperList.getChildren().add(img);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -223,7 +230,7 @@ public class MainFXMLController {
|
|||||||
for (TribeCard card : controller.miniModel.lowerListTribeCards) {
|
for (TribeCard card : controller.miniModel.lowerListTribeCards) {
|
||||||
final int index = i;
|
final int index = i;
|
||||||
StackPane img = createCard(card, true, true, lowerList);
|
StackPane img = createCard(card, true, true, lowerList);
|
||||||
img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index));
|
img.setOnMouseClicked(e -> controller.drawLowerTribeCard(index));
|
||||||
lowerList.getChildren().add(img);
|
lowerList.getChildren().add(img);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -273,7 +280,7 @@ public class MainFXMLController {
|
|||||||
myHand.getChildren().add(img);
|
myHand.getChildren().add(img);
|
||||||
} else {
|
} else {
|
||||||
Region placeholder = new Region();
|
Region placeholder = new Region();
|
||||||
placeholder.prefHeightProperty().bind(myHand.heightProperty().multiply(0.90));
|
placeholder.prefHeightProperty().bind(myHand.getScene().heightProperty().subtract(40).divide(4).multiply(0.90));
|
||||||
placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675));
|
placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675));
|
||||||
placeholder.setStyle("-fx-background-color: transparent;");
|
placeholder.setStyle("-fx-background-color: transparent;");
|
||||||
myHand.getChildren().add(placeholder);
|
myHand.getChildren().add(placeholder);
|
||||||
@@ -282,7 +289,7 @@ public class MainFXMLController {
|
|||||||
|
|
||||||
private void renderPlayer(Player player,VBox target) {
|
private void renderPlayer(Player player,VBox target) {
|
||||||
VBox card = new VBox(3);
|
VBox card = new VBox(3);
|
||||||
VBox.setMargin(card, new Insets(8,15,8,15));
|
VBox.setMargin(card, new Insets(15,15,0,15));
|
||||||
card.getStyleClass().add("player-card");
|
card.getStyleClass().add("player-card");
|
||||||
card.setPadding(new Insets(4));
|
card.setPadding(new Insets(4));
|
||||||
|
|
||||||
@@ -291,6 +298,8 @@ public class MainFXMLController {
|
|||||||
scaleUp.setToX(1.1);
|
scaleUp.setToX(1.1);
|
||||||
scaleUp.setToY(1.1);
|
scaleUp.setToY(1.1);
|
||||||
scaleUp.play();
|
scaleUp.play();
|
||||||
|
|
||||||
|
card.setStyle("-fx-effect: dropshadow(gaussian, #fff8dc, 15, 0.10, 0, 0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -303,8 +312,9 @@ public class MainFXMLController {
|
|||||||
totem.setPreserveRatio(true);
|
totem.setPreserveRatio(true);
|
||||||
Label usernameLabel = new Label(player.getUserName());
|
Label usernameLabel = new Label(player.getUserName());
|
||||||
usernameLabel.getStyleClass().add("label-medium");
|
usernameLabel.getStyleClass().add("label-medium");
|
||||||
|
usernameLabel.setStyle("-fx-text-fill: #711423;");
|
||||||
if (player.getUserName().equals(controller.myUsername)) {
|
if (player.getUserName().equals(controller.myUsername)) {
|
||||||
usernameLabel.setStyle("-fx-text-fill: #9d0208");
|
usernameLabel.setText(usernameLabel.getText() + " (you)");
|
||||||
|
|
||||||
if(isError) {
|
if(isError) {
|
||||||
TranslateTransition tt = new TranslateTransition(Duration.millis(50), card);
|
TranslateTransition tt = new TranslateTransition(Duration.millis(50), card);
|
||||||
@@ -454,7 +464,7 @@ public class MainFXMLController {
|
|||||||
default -> "/GUIImages/Backs/back-001.png";
|
default -> "/GUIImages/Backs/back-001.png";
|
||||||
};
|
};
|
||||||
ImageView back = new ImageView(loadImage(path));
|
ImageView back = new ImageView(loadImage(path));
|
||||||
back.fitHeightProperty().bind(board.heightProperty().multiply(0.94));
|
back.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().divide(4).multiply(0.94));
|
||||||
back.setPreserveRatio(true);
|
back.setPreserveRatio(true);
|
||||||
addClip(back);
|
addClip(back);
|
||||||
addShadow(back);
|
addShadow(back);
|
||||||
@@ -525,7 +535,7 @@ public class MainFXMLController {
|
|||||||
Slot slot = entry.getKey();
|
Slot slot = entry.getKey();
|
||||||
final int index = i;
|
final int index = i;
|
||||||
StackPane img = createSlot(slot, true, true);
|
StackPane img = createSlot(slot, true, true);
|
||||||
img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index));
|
img.setOnMouseClicked(e -> controller.slotChoice(index));
|
||||||
board.getChildren().add(img);
|
board.getChildren().add(img);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -548,7 +558,7 @@ public class MainFXMLController {
|
|||||||
|
|
||||||
private void renderSidePanel() {
|
private void renderSidePanel() {
|
||||||
infoText.setText("Round: "+Integer.toString(controller.miniModel.currentState.getRound()) + " • " + controller.miniModel.currentState.getGameStage().toString());
|
infoText.setText("Round: "+Integer.toString(controller.miniModel.currentState.getRound()) + " • " + controller.miniModel.currentState.getGameStage().toString());
|
||||||
skipBtn.setOnAction(e -> controller.skipTurn(controller.myUsername));
|
skipBtn.setOnAction(e -> controller.skipTurn());
|
||||||
detailsBtn.setOnAction(e -> openDetailsPopup());
|
detailsBtn.setOnAction(e -> openDetailsPopup());
|
||||||
|
|
||||||
addHoverZoom(skipBtn);
|
addHoverZoom(skipBtn);
|
||||||
@@ -609,7 +619,7 @@ public class MainFXMLController {
|
|||||||
StackPane img = createCardPopup(cardList.get(i), true, false);
|
StackPane img = createCardPopup(cardList.get(i), true, false);
|
||||||
img.setOnMouseClicked(e -> {
|
img.setOnMouseClicked(e -> {
|
||||||
popup.hide();
|
popup.hide();
|
||||||
controller.drawUpperBuildingCard(controller.myUsername, index);
|
controller.drawUpperBuildingCard(index);
|
||||||
});
|
});
|
||||||
popupCards.getChildren().add(img);
|
popupCards.getChildren().add(img);
|
||||||
}
|
}
|
||||||
@@ -624,7 +634,7 @@ public class MainFXMLController {
|
|||||||
StackPane img = createCardPopup(cardList.get(i), true, false);
|
StackPane img = createCardPopup(cardList.get(i), true, false);
|
||||||
img.setOnMouseClicked(e -> {
|
img.setOnMouseClicked(e -> {
|
||||||
popup.hide();
|
popup.hide();
|
||||||
controller.drawLowerBuildingCard(controller.myUsername, index);
|
controller.drawLowerBuildingCard(index);
|
||||||
});
|
});
|
||||||
popupCards.getChildren().add(img);
|
popupCards.getChildren().add(img);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ public class TotemFXMLController {
|
|||||||
@FXML
|
@FXML
|
||||||
private void onConfirm() {
|
private void onConfirm() {
|
||||||
if (selectedIndex >= 0) {
|
if (selectedIndex >= 0) {
|
||||||
controller.totemChoice(controller.myUsername, selectedIndex);
|
controller.totemChoice(selectedIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,6 +257,7 @@ public class TUI implements IView {
|
|||||||
table.addRow(List.of("4-DrawLowerTribe(pos)", ""));
|
table.addRow(List.of("4-DrawLowerTribe(pos)", ""));
|
||||||
table.addRow(List.of("5-DrawLowerBuilding(pos)", ""));
|
table.addRow(List.of("5-DrawLowerBuilding(pos)", ""));
|
||||||
table.addRow(List.of("6-SkipTurn", ""));
|
table.addRow(List.of("6-SkipTurn", ""));
|
||||||
|
table.addRow(List.of("0-Disconnect", ""));
|
||||||
return table.build();
|
return table.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,78 +13,78 @@
|
|||||||
fx:controller="it.polimi.ingsw.gc14.View.GUI.MainFXMLController"
|
fx:controller="it.polimi.ingsw.gc14.View.GUI.MainFXMLController"
|
||||||
stylesheets="@styles.css">
|
stylesheets="@styles.css">
|
||||||
|
|
||||||
<children>
|
<children>
|
||||||
<!-- VBox sinistra: si espande per riempire tutto lo spazio disponibile -->
|
<!-- VBox sinistra: si espande per riempire tutto lo spazio disponibile -->
|
||||||
<VBox alignment="CENTER"
|
<VBox alignment="CENTER"
|
||||||
fillWidth="false"
|
fillWidth="false"
|
||||||
maxHeight="Infinity"
|
maxHeight="Infinity"
|
||||||
maxWidth="Infinity"
|
maxWidth="Infinity"
|
||||||
HBox.hgrow="ALWAYS">
|
HBox.hgrow="ALWAYS">
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets top="5" right="5" bottom="5" left="5" />
|
<Insets top="5" right="5" bottom="5" left="5" />
|
||||||
</HBox.margin>
|
</HBox.margin>
|
||||||
<children>
|
<children>
|
||||||
<HBox fx:id="upperList" styleClass="card-list" VBox.vgrow="ALWAYS">
|
<HBox fx:id="upperList" styleClass="card-list" VBox.vgrow="ALWAYS">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets top="5" right="5" bottom="5" left="5" />
|
<Insets top="5" right="5" bottom="5" left="5" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<HBox fx:id="board" prefHeight="280" minHeight="280" maxHeight="280" styleClass="card-list" VBox.vgrow="NEVER">
|
<HBox fx:id="board" styleClass="card-list" VBox.vgrow="NEVER">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets top="5" right="5" bottom="5" left="5" />
|
<Insets top="5" right="5" bottom="5" left="5" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<HBox fx:id="lowerList" styleClass="card-list" VBox.vgrow="ALWAYS">
|
<HBox fx:id="lowerList" styleClass="card-list" VBox.vgrow="ALWAYS">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets top="5" right="5" bottom="5" left="5" />
|
<Insets top="5" right="5" bottom="5" left="5" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<HBox fx:id="myHand" styleClass="card-list" VBox.vgrow="ALWAYS">
|
<HBox fx:id="myHand" styleClass="card-list" VBox.vgrow="ALWAYS">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets top="5" right="5" bottom="5" left="5" />
|
<Insets top="5" right="5" bottom="5" left="5" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
<!-- VBox destra: dimensione fissa, non si espande -->
|
<!-- VBox destra: dimensione fissa, non si espande -->
|
||||||
<VBox fx:id="sidePanel"
|
<VBox fx:id="sidePanel"
|
||||||
prefWidth="250.0"
|
prefWidth="250.0"
|
||||||
maxWidth="250.0"
|
maxWidth="250.0"
|
||||||
minWidth="250.0"
|
minWidth="250.0"
|
||||||
HBox.hgrow="NEVER"
|
HBox.hgrow="NEVER"
|
||||||
styleClass="side-panel">
|
styleClass="side-panel">
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets bottom="10" left="10" right="10" top="10" />
|
<Insets bottom="10" left="10" right="10" top="10" />
|
||||||
</HBox.margin>
|
</HBox.margin>
|
||||||
<children>
|
<children>
|
||||||
<HBox fx:id="info" prefHeight="80.0" prefWidth="483.0" styleClass="frame" alignment="CENTER">
|
<HBox fx:id="info" prefHeight="80.0" prefWidth="483.0" styleClass="frame" alignment="CENTER">
|
||||||
<Label fx:id="infoText" styleClass="label-medium" text="VALORE" />
|
<Label fx:id="infoText" styleClass="label-medium" text="VALORE" />
|
||||||
</HBox>
|
</HBox>
|
||||||
<ScrollPane fx:id="playerSide" fitToWidth="true"
|
<ScrollPane fx:id="playerSide" fitToWidth="true"
|
||||||
style="-fx-background: transparent; -fx-background-color: transparent;" hbarPolicy="NEVER"
|
style="-fx-background: transparent; -fx-background-color: transparent;" hbarPolicy="NEVER"
|
||||||
vbarPolicy="AS_NEEDED" VBox.vgrow="ALWAYS">
|
vbarPolicy="AS_NEEDED" VBox.vgrow="ALWAYS">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets top="5"/>
|
<Insets top="5"/>
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
<Pane HBox.hgrow="ALWAYS"/>
|
<Pane HBox.hgrow="ALWAYS"/>
|
||||||
<HBox alignment="CENTER" fx:id="buttonRow" >
|
<HBox alignment="CENTER" fx:id="buttonRow" >
|
||||||
<HBox spacing="10">
|
<HBox spacing="10">
|
||||||
<Button fx:id="skipBtn" styleClass="action-button" text="Skip Turn"/>
|
<Button fx:id="skipBtn" styleClass="action-button" text="Skip Turn"/>
|
||||||
<Button fx:id="detailsBtn" styleClass="action-button" text="Ending Details"/>
|
<Button fx:id="detailsBtn" styleClass="action-button" text="Ending Details"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets top="5" right="5" bottom="5" left="5"/>
|
<Insets top="5" right="5" bottom="5" left="5"/>
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
|
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
|
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|
||||||
</children>
|
</children>
|
||||||
</HBox>
|
</HBox>
|
||||||
@@ -35,11 +35,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.player-card {
|
.player-card {
|
||||||
-fx-border-color: #6a040f;
|
-fx-border-color: #711423;
|
||||||
-fx-border-width: 2;
|
-fx-border-width: 2;
|
||||||
-fx-border-radius: 15;
|
-fx-border-radius: 15;
|
||||||
-fx-background-radius: 15;
|
-fx-background-radius: 15;
|
||||||
-fx-background-color: #f48c06;
|
-fx-background-color: #f18f1c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame {
|
.frame {
|
||||||
|
|||||||
Reference in New Issue
Block a user