diff --git a/pom.xml b/pom.xml index 428f8b5..b05ab02 100644 --- a/pom.xml +++ b/pom.xml @@ -62,14 +62,19 @@ maven-compiler-plugin 3.13.0 - 25 - 25 + 25 + + --enable-preview + org.apache.maven.plugins maven-surefire-plugin 3.2.5 + + --enable-preview + org.openjfx @@ -77,7 +82,6 @@ 0.0.8 - default-cli it.polimi.ingsw.gc14.HelloApplication diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java index a0a42c1..ed81083 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java @@ -206,12 +206,6 @@ public class GameController { return model.totemChoice(player, Totems.valueOf(totem)); } - /** - * @deprecated Use {@link #endGameForFeit()} instead. - */ - @Deprecated - public synchronized void EndGameForFeit() { endGameForFeit(); } - /** * Ends the game due to forfeit: all remaining players are absent, * so the game is terminated and final scores are computed. diff --git a/src/main/java/it/polimi/ingsw/gc14/GameEventProcessor.java b/src/main/java/it/polimi/ingsw/gc14/GameEventProcessor.java index d4436d7..2e6e0af 100644 --- a/src/main/java/it/polimi/ingsw/gc14/GameEventProcessor.java +++ b/src/main/java/it/polimi/ingsw/gc14/GameEventProcessor.java @@ -282,7 +282,7 @@ public class GameEventProcessor { synchronized (gameController) { gameController.endGameForFeit(); EndedGame forfeitEnd = new EndedGame( - game.getSlotMap(), game.orderLogicCard, + game.getSlotMap(), game.getOrderLogicCard(), game.getCurrentState(), game.getPlayerStanding() ); broadcaster.notifyAll(forfeitEnd); @@ -313,7 +313,7 @@ public class GameEventProcessor { broadcaster.notifyAll(event); if (game.getCurrentState().getRound() != roundBefore) { ApplyNextRound nextRound = new ApplyNextRound( - game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), + game.getSlotMap(), game.getOrderLogicCard(), game.getCurrentState(), game.getPlayers(), game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding() @@ -321,7 +321,7 @@ public class GameEventProcessor { broadcaster.notifyAll(nextRound); } else if (game.getCurrentState().getGameStage() == GameStages.ENDED) { EndedGame endedGame = new EndedGame( - game.getSlotMap(), game.orderLogicCard, + game.getSlotMap(), game.getOrderLogicCard(), game.getCurrentState(), game.getPlayerStanding() ); broadcaster.notifyAll(endedGame); @@ -349,7 +349,7 @@ public class GameEventProcessor { * @return a new {@link ArrayList} of disconnected usernames. */ private ArrayList buildDisconnectedList(Game game) { - return game.disconnetedPlayers.entrySet().stream() + return game.disconnectedPlayers.entrySet().stream() .filter(Map.Entry::getValue) .map(e -> e.getKey().getUserName()) .collect(Collectors.toCollection(ArrayList::new)); diff --git a/src/main/java/it/polimi/ingsw/gc14/LimitedMap.java b/src/main/java/it/polimi/ingsw/gc14/LimitedMap.java index c9e7c5f..afaf634 100644 --- a/src/main/java/it/polimi/ingsw/gc14/LimitedMap.java +++ b/src/main/java/it/polimi/ingsw/gc14/LimitedMap.java @@ -63,37 +63,37 @@ public class LimitedMap implements Map { } @Override - public synchronized V remove(Object key) { return map.remove(key); } + public V remove(Object key) { return map.remove(key); } @Override - public synchronized V get(Object key) { return map.get(key); } + public V get(Object key) { return map.get(key); } @Override - public synchronized boolean containsKey(Object key) { return map.containsKey(key); } + public boolean containsKey(Object key) { return map.containsKey(key); } @Override - public synchronized boolean containsValue(Object value) { return map.containsValue(value); } + public boolean containsValue(Object value) { return map.containsValue(value); } @Override - public synchronized int size() { return map.size(); } + public int size() { return map.size(); } @Override - public synchronized boolean isEmpty() { return map.isEmpty(); } + public boolean isEmpty() { return map.isEmpty(); } @Override - public synchronized void putAll(Map m) { m.forEach(this::put); } + public void putAll(Map m) { m.forEach(this::put); } @Override - public synchronized void clear() { map.clear(); } + public void clear() { map.clear(); } @Override - public synchronized Set keySet() { return map.keySet(); } + public Set keySet() { return map.keySet(); } @Override - public synchronized Collection values() { return map.values(); } + public Collection values() { return map.values(); } @Override - public synchronized Set> entrySet() { return map.entrySet(); } + public Set> entrySet() { return map.entrySet(); } /** * Sets a new size limit for this map. diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java index 95ab655..059b88a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -102,7 +102,7 @@ public class Game implements Serializable { } else { - while(disconnetedPlayers.containsKey(nextPlayer)&& disconnetedPlayers.get(nextPlayer)) + while(disconnectedPlayers.containsKey(nextPlayer)&& disconnectedPlayers.get(nextPlayer)) { nextPlayer.setTotem(getAvailableTotems().get(new Random().nextInt(0,getAvailableTotems().size()))); nextPlayer=totemChoiceQueue.poll(); @@ -121,7 +121,7 @@ public class Game implements Serializable { /** * Map tracking the players who are currently disconnected. */ - public Map disconnetedPlayers = new HashMap<>(); + public Map disconnectedPlayers = new HashMap<>(); /** * Marks the specified player as disconnected and updates the game flow accordingly. @@ -137,11 +137,11 @@ public class Game implements Serializable { */ public synchronized boolean disconnectedPlayer(Player player) { - if(disconnetedPlayers.containsKey(player) && disconnetedPlayers.get(player)) + if(disconnectedPlayers.containsKey(player) && disconnectedPlayers.get(player)) { return false; } - disconnetedPlayers.put(player,true); + disconnectedPlayers.put(player,true); if (currentState.getGameStage().equals(GameStages.WAITING)) { playersList.remove(player); totemChoiceQueue.remove(player); @@ -179,14 +179,14 @@ public class Game implements Serializable { */ public synchronized boolean reconnectPlayer(Player player) { - if(!disconnetedPlayers.containsKey(player)) + if(!disconnectedPlayers.containsKey(player)) { return false; } - disconnetedPlayers.put(player,false); + disconnectedPlayers.put(player,false); if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE) ) { - disconnetedPlayers.remove(player); + disconnectedPlayers.remove(player); if(!orderLogicCard.players.contains(player)) { orderLogicCard.pushNoEffect(player); @@ -195,7 +195,7 @@ public class Game implements Serializable { else if(currentState.getGameStage().equals(GameStages.RES_ACTIONS)) { if(slotMap.containsValue(player)) { - disconnetedPlayers.remove(player); + disconnectedPlayers.remove(player); } } return true; @@ -206,7 +206,7 @@ public class Game implements Serializable { */ public synchronized void ClearDisconnected() { - disconnetedPlayers.clear(); + disconnectedPlayers.clear(); } /** @@ -252,7 +252,14 @@ public class Game implements Serializable { /** * The order logic card associated with this game. */ - public OrderLogicCard orderLogicCard; + private OrderLogicCard orderLogicCard; + + /** + * Returns the order logic card associated with this game. + * + * @return the order logic card. + */ + public OrderLogicCard getOrderLogicCard() { return orderLogicCard; } /** * The board associated with this game. @@ -698,7 +705,7 @@ public class Game implements Serializable { if (GameStages.SLOT_CHOICE == currentState.getGameStage()) { Player tempPlayer = orderLogicCard.pull(); - if(disconnetedPlayers.containsKey(tempPlayer) && disconnetedPlayers.get(tempPlayer)) { + if(disconnectedPlayers.containsKey(tempPlayer) && disconnectedPlayers.get(tempPlayer)) { nextPlayerSetup(); return; } @@ -750,7 +757,7 @@ public class Game implements Serializable { for (Map.Entry entry : slotMap.entrySet()) { if (entry.getValue() != null) { - if(disconnetedPlayers.containsKey(entry.getValue())&&disconnetedPlayers.get(entry.getValue())) + if(disconnectedPlayers.containsKey(entry.getValue())&& disconnectedPlayers.get(entry.getValue())) { orderLogicCard.push(entry.getValue()); entry.setValue(null); @@ -782,7 +789,7 @@ public class Game implements Serializable { if (optionalPlayer != null) { currentState.PlayerUpdate(optionalPlayer, null); - if(disconnetedPlayers.containsKey(currentState.getCurrentPlayer())&& disconnetedPlayers.get(currentState.getCurrentPlayer())) { + if(disconnectedPlayers.containsKey(currentState.getCurrentPlayer())&& disconnectedPlayers.get(currentState.getCurrentPlayer())) { nextPlayerSetup(); } return; @@ -815,7 +822,7 @@ public class Game implements Serializable { for (Player p :playersList) { long count = p.getBuildingCards().stream().filter(x -> x.getEffectId() == 12).count(); if (count > 0) { - if(disconnetedPlayers.containsKey(p)&& disconnetedPlayers.get(p)) + if(disconnectedPlayers.containsKey(p)&& disconnectedPlayers.get(p)) { continue; } @@ -832,12 +839,12 @@ public class Game implements Serializable { if (currentState.getRound() < 10) { nextRound(); - for(Map.Entry entry: disconnetedPlayers.entrySet()) + for(Map.Entry entry: disconnectedPlayers.entrySet()) { if(!entry.getValue()) { orderLogicCard.pushNoEffect(entry.getKey()); - disconnetedPlayers.remove(entry.getKey()); + disconnectedPlayers.remove(entry.getKey()); } else { @@ -999,7 +1006,7 @@ public class Game implements Serializable { * ordered by prestige value and, in case of a tie, by food value. */ public synchronized void endGameForFeit() { - Player winner=playersList.stream().filter(x->!disconnetedPlayers.containsKey(x)||!disconnetedPlayers.get(x)).toList().get(0); + Player winner=playersList.stream().filter(x->!disconnectedPlayers.containsKey(x)||!disconnectedPlayers.get(x)).toList().get(0); currentState.GameStageUpdate(GameStages.ENDED); playerStanding=new ArrayList<>(playersList); playerStanding.remove(winner); diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java index 62f212f..b918666 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java @@ -99,7 +99,7 @@ public abstract class NetworkEvent implements Serializable { * @param disconnectedUsernames usernames of currently disconnected players. */ public void enrichWithGameState(Game game, ArrayList disconnectedUsernames) { - setData(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers()); + setData(game.getSlotMap(), game.getOrderLogicCard(), game.getCurrentState(), game.getPlayers()); } /** diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java index db906d5..d40ccee 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java @@ -126,7 +126,7 @@ public class RMIClient implements IClient { if (!running) return; running = false; if (pingSender != null) pingSender.shutdownNow(); - controller.miniModel=null; + controller.setModel(null); controller.setClient(null); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java index e3f141c..5493ed9 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java @@ -16,7 +16,6 @@ import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; -import java.util.Collections; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; @@ -130,7 +129,7 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer { System.out.println("Reconnected player: " + username); startWatchdog(username); Game game = controller.getModel(); - callback.onGameInit(new MiniModel(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers(), game.getAvailableTotems(), game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)))); + callback.onGameInit(new MiniModel(game.getSlotMap(), game.getOrderLogicCard(), game.getCurrentState(), game.getPlayers(), game.getAvailableTotems(), game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), game.disconnectedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)))); System.out.println("Model sent: " + username); actionQueue.add(new ReconnectPlayer(username)); return null; diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java index e4291a0..867266b 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java @@ -262,11 +262,11 @@ public class TCPServer { Game game = controller.getModel(); handler.notifyMiniModel(new MiniModel( game.getSlotMap(), - game.orderLogicCard, + game.getOrderLogicCard(), game.getCurrentState(), game.getPlayers(), game.getAvailableTotems(), - game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)) + game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), game.disconnectedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)) )); Thread thread = new Thread(handler); diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index 8995818..c8e628a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -95,11 +95,11 @@ public class ServerLauncher { synchronized (gameController) { Game game = gameController.getModel(); miniModel = new MiniModel( - game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), + game.getSlotMap(), game.getOrderLogicCard(), game.getCurrentState(), game.getPlayers(), game.getAvailableTotems(), game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), - game.disconnetedPlayers.entrySet().stream() + game.disconnectedPlayers.entrySet().stream() .filter(Map.Entry::getValue) .map(e -> e.getKey().getUserName()) .collect(Collectors.toCollection(ArrayList::new)) @@ -127,16 +127,11 @@ public class ServerLauncher { * Runs the event-processing loop until the thread is interrupted. * *

A {@link ConcurrentModificationException} is caught and logged rather - * than propagated; it is caused by an unsafe {@link ArrayList} in - * {@code TCPServer.clientHandlers} (tracked as a separate issue) and does - * not leave the game in an inconsistent state. */ public void run() { while (true) { try { eventProcessor.doFirstEvent(); - } catch (ConcurrentModificationException e) { - System.err.println("Concurrent modification in notifyAll — skipping tick"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; @@ -167,7 +162,7 @@ public class ServerLauncher { Game game = saveManager.load(); if (game == null) return; - long disconnectedCount = game.disconnetedPlayers.entrySet().stream() + long disconnectedCount = game.disconnectedPlayers.entrySet().stream() .filter(Map.Entry::getValue).count(); if (disconnectedCount >= game.getNPlayers() - 1) { @@ -179,7 +174,7 @@ public class ServerLauncher { gameController.setModel(game); playerList.setLimit(game.getNPlayers()); - for (Map.Entry entry : game.disconnetedPlayers.entrySet()) { + for (Map.Entry entry : game.disconnectedPlayers.entrySet()) { if (entry.getValue()) { playerList.put(entry.getKey().getUserName(), false); } diff --git a/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java b/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java index e4bc168..7782290 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java @@ -263,8 +263,8 @@ class GameControllerTest { assertTrue(controller.disconnectedPlayer(current.getUserName())); - assertTrue(game.disconnetedPlayers.containsKey(current)); - assertTrue(game.disconnetedPlayers.get(current)); + assertTrue(game.disconnectedPlayers.containsKey(current)); + assertTrue(game.disconnectedPlayers.get(current)); } @Test diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java index fa30059..8a816ea 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -1341,8 +1341,8 @@ class GameTest { assertTrue(game.disconnectedPlayer(current)); - assertTrue(game.disconnetedPlayers.containsKey(current)); - assertTrue(game.disconnetedPlayers.get(current)); + assertTrue(game.disconnectedPlayers.containsKey(current)); + assertTrue(game.disconnectedPlayers.get(current)); assertNotEquals(current, game.getCurrentState().getCurrentPlayer()); } @@ -1367,10 +1367,10 @@ class GameTest { Player current = game.getCurrentState().getCurrentPlayer(); assertTrue(game.disconnectedPlayer(current)); - assertTrue(game.disconnetedPlayers.containsKey(current)); + assertTrue(game.disconnectedPlayers.containsKey(current)); assertTrue(game.reconnectPlayer(current)); - assertFalse(game.disconnetedPlayers.containsKey(current)); + assertFalse(game.disconnectedPlayers.containsKey(current)); } @Test @@ -1382,11 +1382,11 @@ class GameTest { Player current = game.getCurrentState().getCurrentPlayer(); assertTrue(game.disconnectedPlayer(current)); - assertFalse(game.disconnetedPlayers.isEmpty()); + assertFalse(game.disconnectedPlayers.isEmpty()); game.ClearDisconnected(); - assertTrue(game.disconnetedPlayers.isEmpty()); + assertTrue(game.disconnectedPlayers.isEmpty()); } @Test