Merge branch 'main' into GUI-2.0
This commit is contained in:
@@ -93,11 +93,7 @@ public class ClientController {
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
client.drawUpperTribeCard(playerUsername, pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.drawUpperTribeCard(playerUsername, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,11 +108,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else
|
||||
try {
|
||||
client.drawLowerTribeCard(playerUsername, pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.drawLowerTribeCard(playerUsername, pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,11 +122,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.drawUpperBuildingCard(playerUsername,pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.drawUpperBuildingCard(playerUsername,pos);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -150,11 +138,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername,miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.drawLowerBuildingCard(playerUsername,pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.drawLowerBuildingCard(playerUsername,pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,11 +152,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername,miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.skipTurn(playerUsername);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.skipTurn(playerUsername);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,11 +169,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername,miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.pickOptionalTribeCard(playerUsername,pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.pickOptionalTribeCard(playerUsername,pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,11 +184,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.pickOptionalBuildingCard(playerUsername,pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.pickOptionalBuildingCard(playerUsername,pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,11 +198,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.noOptionalCard(playerUsername);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.noOptionalCard(playerUsername);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,11 +212,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.slotChoice(playerUsername,pos);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.slotChoice(playerUsername,pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,11 +221,7 @@ public class ClientController {
|
||||
if(!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName()))
|
||||
view.showError("It's not your turn!");
|
||||
else {
|
||||
try {
|
||||
client.totemChoice(playerUsername, String.valueOf(miniModel.availableTotems.get(pos)));
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
client.totemChoice(playerUsername, String.valueOf(miniModel.availableTotems.get(pos)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A {@link LinkedHashMap} with a configurable size limit and an associated action.
|
||||
@@ -15,7 +16,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class LimitedMap<K, V> implements Map<K, V> {
|
||||
|
||||
private final LinkedHashMap<K, V> map = new LinkedHashMap<>();
|
||||
private final ConcurrentHashMap<K, V> map = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* The maximum number of elements allowed in the map before the action is triggered.
|
||||
|
||||
@@ -96,20 +96,26 @@ public class Game implements Serializable {
|
||||
return false;
|
||||
}
|
||||
disconnetedPlayers.put(player,true);
|
||||
if(currentState.getCurrentPlayer().equals(player))
|
||||
if(!currentState.getGameStage().equals(GameStages.TOTEM_CHOICE))
|
||||
if (currentState.getGameStage().equals(GameStages.WAITING)) {
|
||||
playersList.remove(player);
|
||||
totemChoiceQueue.remove(player);
|
||||
return true;
|
||||
}
|
||||
if(currentState.getCurrentPlayer().equals(player)) {
|
||||
if (!currentState.getGameStage().equals(GameStages.TOTEM_CHOICE)) {
|
||||
nextPlayerSetup();
|
||||
else
|
||||
{
|
||||
if(totemChoiceQueue.isEmpty())
|
||||
{
|
||||
player.totem=getAvailableTotems().get(new Random().nextInt(getAvailableTotems().size()-1));
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (totemChoiceQueue.isEmpty()) {
|
||||
player.totem = getAvailableTotems().get(new Random().nextInt(getAvailableTotems().size() - 1));
|
||||
} else {
|
||||
totemChoiceQueue.add(player);
|
||||
}
|
||||
currentState.PlayerUpdate(totemChoiceQueue.poll(),null);
|
||||
currentState.PlayerUpdate(totemChoiceQueue.poll(), null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,11 @@ public abstract class OrderLogicCard implements Serializable {
|
||||
playerList=new ArrayList<>();
|
||||
|
||||
}
|
||||
if(players.stream().anyMatch(x->x.getUserName().equals(player.getUserName())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
playerList.removeIf(x->player.getUserName().equals(x.player.getUserName()));
|
||||
playerList.add(new OrderPlayer(player,false));
|
||||
players.add(player);
|
||||
}
|
||||
|
||||
@@ -8,26 +8,26 @@ import java.util.Objects;
|
||||
public interface IClient {
|
||||
public boolean connect(String username,int preferredInt);
|
||||
|
||||
public void drawUpperTribeCard(String playerUsername, int pos) throws RemoteException;
|
||||
public void drawUpperTribeCard(String playerUsername, int pos) ;
|
||||
|
||||
public void drawLowerTribeCard(String playerUsername,int pos) throws RemoteException;
|
||||
public void drawLowerTribeCard(String playerUsername,int pos) ;
|
||||
|
||||
public void drawUpperBuildingCard(String playerUsername,int pos) throws RemoteException;
|
||||
public void drawUpperBuildingCard(String playerUsername,int pos) ;
|
||||
|
||||
|
||||
public void drawLowerBuildingCard(String playerUsername,int pos) throws RemoteException;
|
||||
public void drawLowerBuildingCard(String playerUsername,int pos) ;
|
||||
|
||||
public void skipTurn(String playerUsername) throws RemoteException;
|
||||
public void skipTurn(String playerUsername);
|
||||
|
||||
|
||||
|
||||
public void pickOptionalTribeCard(String playerUsername,int pos) throws RemoteException;
|
||||
public void pickOptionalTribeCard(String playerUsername,int pos) ;
|
||||
|
||||
public void pickOptionalBuildingCard(String playerUsername,int pos) throws RemoteException;
|
||||
public void pickOptionalBuildingCard(String playerUsername,int pos) ;
|
||||
|
||||
|
||||
public void noOptionalCard(String playerUsername) throws RemoteException;
|
||||
public void noOptionalCard(String playerUsername) ;
|
||||
|
||||
public void slotChoice(String playerUsername,int pos) throws RemoteException;
|
||||
public void totemChoice(String playerUsername,String totem) throws RemoteException;
|
||||
public void slotChoice(String playerUsername,int pos) ;
|
||||
public void totemChoice(String playerUsername,String totem) ;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,13 @@ public class DisconnectedPlayer extends NetworkEvent implements Serializable{
|
||||
public boolean apply(MiniModel miniModel){
|
||||
if(isError)
|
||||
return false;
|
||||
miniModel.setPlayer(player);
|
||||
miniModel.setOrderLogicCard(orderLogicCard);
|
||||
miniModel.setCurrentState(currentState);
|
||||
miniModel.setSlotPlayerMap(slotPlayerMap);
|
||||
if(miniModel!=null)
|
||||
{
|
||||
miniModel.setPlayer(player);
|
||||
miniModel.setOrderLogicCard(orderLogicCard);
|
||||
miniModel.setCurrentState(currentState);
|
||||
miniModel.setSlotPlayerMap(slotPlayerMap);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,12 @@ public class ReconnectPlayer extends NetworkEvent implements Serializable{
|
||||
public boolean apply(MiniModel miniModel){
|
||||
if(isError)
|
||||
return false;
|
||||
miniModel.setPlayer(player);
|
||||
miniModel.setOrderLogicCard(orderLogicCard);
|
||||
miniModel.setCurrentState(currentState);
|
||||
miniModel.setSlotPlayerMap(slotPlayerMap);
|
||||
if(miniModel!=null) {
|
||||
miniModel.setPlayer(player);
|
||||
miniModel.setOrderLogicCard(orderLogicCard);
|
||||
miniModel.setCurrentState(currentState);
|
||||
miniModel.setSlotPlayerMap(slotPlayerMap);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,8 +134,13 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the card to draw
|
||||
*/
|
||||
public void drawUpperTribeCard(String playerUsername, int pos) throws RemoteException {
|
||||
stub.drawUpperTribeCard(playerUsername,pos);
|
||||
public void drawUpperTribeCard(String playerUsername, int pos) {
|
||||
try{
|
||||
stub.drawUpperTribeCard(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote draw upper tribe card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,8 +150,13 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the card to draw
|
||||
*/
|
||||
public void drawLowerTribeCard(String playerUsername,int pos) throws RemoteException {
|
||||
stub.drawLowerTribeCard(playerUsername,pos);
|
||||
public void drawLowerTribeCard(String playerUsername,int pos) {
|
||||
try{
|
||||
stub.drawLowerTribeCard(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote draw lower tribe card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,8 +166,13 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the card to draw
|
||||
*/
|
||||
public void drawUpperBuildingCard(String playerUsername,int pos) throws RemoteException {
|
||||
stub.drawUpperBuildingCard(playerUsername,pos);
|
||||
public void drawUpperBuildingCard(String playerUsername,int pos) {
|
||||
try{
|
||||
stub.drawUpperBuildingCard(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote draw upper building card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -167,8 +182,13 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the card to draw
|
||||
*/
|
||||
public void drawLowerBuildingCard(String playerUsername,int pos) throws RemoteException {
|
||||
stub.drawLowerBuildingCard(playerUsername,pos);
|
||||
public void drawLowerBuildingCard(String playerUsername,int pos) {
|
||||
try{
|
||||
stub.drawLowerBuildingCard(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote draw lower building card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,8 +197,13 @@ public class RMIClient implements IClient {
|
||||
* This action is available only when the player cannot draw any tribe card, but still can buy some buildings.
|
||||
* @param playerUsername the name of the player performing the action
|
||||
*/
|
||||
public void skipTurn(String playerUsername) throws RemoteException {
|
||||
stub.skipTurn(playerUsername);
|
||||
public void skipTurn(String playerUsername) {
|
||||
try{
|
||||
stub.skipTurn(playerUsername);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote skip turn");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -190,8 +215,13 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the card to draw
|
||||
*/
|
||||
public void pickOptionalTribeCard(String playerUsername,int pos) throws RemoteException {
|
||||
stub.pickOptionalTribeCard(playerUsername,pos);
|
||||
public void pickOptionalTribeCard(String playerUsername,int pos) {
|
||||
try{
|
||||
stub.pickOptionalTribeCard(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote pick optional tribe card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,8 +231,13 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the card to draw
|
||||
*/
|
||||
public void pickOptionalBuildingCard(String playerUsername,int pos) throws RemoteException {
|
||||
stub.pickOptionalBuildingCard(playerUsername,pos);
|
||||
public void pickOptionalBuildingCard(String playerUsername,int pos) {
|
||||
try{
|
||||
stub.pickOptionalBuildingCard(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote pick optional building card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,8 +246,13 @@ public class RMIClient implements IClient {
|
||||
* Available only if the player owns the building 12.
|
||||
* @param playerUsername the name of the player performing the action
|
||||
*/
|
||||
public void noOptionalCard(String playerUsername) throws RemoteException {
|
||||
stub.noOptionalCard(playerUsername);
|
||||
public void noOptionalCard(String playerUsername) {
|
||||
try{
|
||||
stub.noOptionalCard(playerUsername);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote no pick optional card");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,12 +261,22 @@ public class RMIClient implements IClient {
|
||||
* @param playerUsername the name of the player performing the action
|
||||
* @param pos the index of the selected slot
|
||||
*/
|
||||
public void slotChoice(String playerUsername,int pos) throws RemoteException {
|
||||
stub.slotChoice(playerUsername,pos);
|
||||
public void slotChoice(String playerUsername,int pos) {
|
||||
try{
|
||||
stub.slotChoice(playerUsername,pos);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote slot choice");
|
||||
}
|
||||
}
|
||||
//TODO
|
||||
public void totemChoice(String playerUsername,String totem) throws RemoteException {
|
||||
stub.totemChoice(playerUsername,totem);
|
||||
public void totemChoice(String playerUsername,String totem) {
|
||||
try{
|
||||
stub.totemChoice(playerUsername,totem);
|
||||
}
|
||||
catch (RemoteException e){
|
||||
System.out.println("Error during remote totem choice");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -153,11 +153,17 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
* Also updates every watchdog with the latest model so disconnect logic
|
||||
* knows whose turn it is.
|
||||
*/
|
||||
public void notifyAll(NetworkEvent action) throws RemoteException {
|
||||
public void notifyAll(NetworkEvent action){
|
||||
for (Map.Entry<String, IClientCallback> entry : clients.entrySet()) {
|
||||
if (!action.getIsError() ||
|
||||
(action.getIsError() && action.getUsername().equals(entry.getKey()))) {
|
||||
entry.getValue().onAction(action);
|
||||
try{
|
||||
entry.getValue().onAction(action);
|
||||
}
|
||||
catch (RemoteException e)
|
||||
{
|
||||
System.out.println("Remote exception: Exception during action sending attempt " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,13 +173,19 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
* Mirrors {@code TCPServer.notifyAll(Game)} + the {@code ClientHandler.notifyModel}
|
||||
* call that stores the model for disconnect-turn checking.
|
||||
*/
|
||||
public void notifyAll(MiniModel model) throws RemoteException {
|
||||
public void notifyAll(MiniModel model) {
|
||||
// Keep every watchdog's game reference up to date
|
||||
synchronized (controller){
|
||||
watchdogs.values().forEach(wd -> wd.setGame(controller.getModel()));
|
||||
}
|
||||
for (IClientCallback cb : clients.values()) {
|
||||
cb.onGameInit(model);
|
||||
try{
|
||||
cb.onGameInit(model);
|
||||
}
|
||||
catch (RemoteException e)
|
||||
{
|
||||
System.out.println("Remote exception: Exception during model sending attempt " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,12 +69,10 @@ public class TCPClient implements IClient {
|
||||
*/
|
||||
public boolean connect(String user, int proposedNPlayers) {
|
||||
try {
|
||||
// Socket principale
|
||||
communicationSocket = new Socket(hostname, mainPort);
|
||||
socketSend = new ObjectOutputStream(communicationSocket.getOutputStream());
|
||||
socketReceive = new ObjectInputStream(communicationSocket.getInputStream());
|
||||
NetworkEvent event= new AddPlayer(user, proposedNPlayers);
|
||||
System.out.println("Sending event: " + event);
|
||||
socketSend.writeObject(event);
|
||||
int read= communicationSocket.getInputStream().read();
|
||||
if ( read== -1) {
|
||||
@@ -94,8 +92,6 @@ public class TCPClient implements IClient {
|
||||
new Thread(this::heartbeatLoop, "heartbeat").start();
|
||||
|
||||
running = true;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
} catch (IOException e) {
|
||||
@@ -105,7 +101,6 @@ public class TCPClient implements IClient {
|
||||
}
|
||||
|
||||
private void heartbeatLoop() {
|
||||
// thread che manda ping ogni 3s
|
||||
ScheduledExecutorService sender = Executors.newSingleThreadScheduledExecutor();
|
||||
sender.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
@@ -117,7 +112,6 @@ public class TCPClient implements IClient {
|
||||
}
|
||||
}, 0, 3, TimeUnit.SECONDS);
|
||||
|
||||
// thread corrente: aspetta pong con timeout
|
||||
try {
|
||||
heartbeatSocket.setSoTimeout(5_000);
|
||||
while (running) {
|
||||
@@ -142,7 +136,7 @@ public class TCPClient implements IClient {
|
||||
running = false;
|
||||
try { communicationSocket.close(); } catch (IOException ignored) {}
|
||||
try { heartbeatSocket.close(); } catch (IOException ignored) {}
|
||||
controller.view.showError("Connessione al server persa");
|
||||
controller.view.showError("Connection with server lost");
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +156,7 @@ public class TCPClient implements IClient {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
if (read instanceof NetworkEvent event) { //TODO: avoid instanceof
|
||||
if (read instanceof NetworkEvent event) {
|
||||
if (event.getIsError()) {
|
||||
controller.view.showError(event.toString());
|
||||
} else {
|
||||
@@ -285,7 +279,6 @@ public class TCPClient implements IClient {
|
||||
private void doEvent(NetworkEvent event) {
|
||||
try {
|
||||
synchronized (socketSend) {
|
||||
System.out.println("Sending event: " + event);
|
||||
socketSend.writeObject(event);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -97,9 +97,8 @@ public class ServerLauncher {
|
||||
* All clients (both TCP and RMI) are notified of the event
|
||||
* @return the outcome of applying the event to the controller
|
||||
* @throws InterruptedException if an error occurs while accessing the actionQueue
|
||||
* @throws RemoteException if an RMI error occurs
|
||||
*/
|
||||
public boolean doFirstEvent() throws InterruptedException, RemoteException {
|
||||
public boolean doFirstEvent() throws InterruptedException {
|
||||
NetworkEvent event = actionQueue.take();
|
||||
if(gameController.getModel()!=null && !gameController.getModel().getCurrentState().equals(GameStages.ENDED))
|
||||
{
|
||||
@@ -114,19 +113,27 @@ public class ServerLauncher {
|
||||
disconnectionTimer.cancel(false);
|
||||
disconnectionTimer = null;
|
||||
}
|
||||
int roundPrec=gameController.getModel().getCurrentState().getRound();
|
||||
int roundPrev=gameController.getModel().getCurrentState().getRound();
|
||||
synchronized(gameController){
|
||||
event.setIsError(!event.apply(gameController));
|
||||
Game game=gameController.getModel();
|
||||
if(!event.getIsError())
|
||||
{
|
||||
event.setData(game.getSlotMap(),game.orderLogicCard,game.getCurrentState(),game.getPlayerByUsername(event.getUsername()));
|
||||
if(event.getEventType().equals(EventType.TOTEM_CHOICE))
|
||||
((TotemChoice)event).setAvailableTotems(gameController.getModel().getAvailableTotems());
|
||||
if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER)&& game.getCurrentState().getGameStage().equals(GameStages.WAITING))
|
||||
{
|
||||
playerList.remove(event.getUsername());
|
||||
}else {
|
||||
event.setData(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayerByUsername(event.getUsername()));
|
||||
if (event.getEventType().equals(EventType.TOTEM_CHOICE)) {
|
||||
((TotemChoice) event).setAvailableTotems(gameController.getModel().getAvailableTotems());
|
||||
} else if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && game.getCurrentState().equals(GameStages.WAITING)) {
|
||||
playerList.remove(event.getUsername());
|
||||
}
|
||||
}
|
||||
}
|
||||
serverRMI.notifyAll(event);
|
||||
serverTCP.notifyAll(event);
|
||||
if(game.getCurrentState().getRound()!=roundPrec)
|
||||
if(game.getCurrentState().getRound()!=roundPrev)
|
||||
{
|
||||
ApplyNextRound nextRound=new ApplyNextRound(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayers());
|
||||
serverRMI.notifyAll(nextRound);
|
||||
@@ -147,15 +154,14 @@ public class ServerLauncher {
|
||||
else if(!this.gameSave() ){
|
||||
System.out.println("\n!!! Save failed !!!\n");
|
||||
}
|
||||
|
||||
}
|
||||
if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1) {
|
||||
if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1&& game.getCurrentState().getGameStage() != GameStages.ENDED) {
|
||||
if (disconnectionTimer != null && !disconnectionTimer.isDone()) {
|
||||
disconnectionTimer.cancel(false);
|
||||
}
|
||||
disconnectionTimer = timerExecutor.schedule(() -> {
|
||||
System.out.println("Timer scaduto: nessun giocatore riconnesso in 30s.");
|
||||
}, 30, TimeUnit.SECONDS);
|
||||
System.out.println("Timer expired: no player reconnected in 60s.");
|
||||
}, 1, TimeUnit.MINUTES);
|
||||
}
|
||||
return !event.getIsError();
|
||||
}
|
||||
@@ -214,29 +220,24 @@ public class ServerLauncher {
|
||||
}
|
||||
playerList.setAction(()->{
|
||||
new Thread(()->{
|
||||
try {
|
||||
System.out.println("\n\nNotifying model");
|
||||
MiniModel miniModel;
|
||||
synchronized (gameController) {
|
||||
Game game = gameController.getModel();
|
||||
miniModel= new MiniModel(game.getBoard(),game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(), new ArrayList<>(List.of(Totems.values())));
|
||||
}
|
||||
serverRMI.notifyAll(miniModel);
|
||||
serverTCP.notifyAll(miniModel);
|
||||
view = new TUI(miniModel);
|
||||
view.fullRender();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
System.out.println("\n\nNotifying model");
|
||||
MiniModel miniModel;
|
||||
synchronized (gameController) {
|
||||
Game game = gameController.getModel();
|
||||
miniModel= new MiniModel(game.getBoard(),game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(), new ArrayList<>(List.of(Totems.values())));
|
||||
}
|
||||
serverRMI.notifyAll(miniModel);
|
||||
serverTCP.notifyAll(miniModel);
|
||||
view = new TUI(miniModel);
|
||||
view.fullRender();
|
||||
}).start();
|
||||
});
|
||||
new Thread(()-> {
|
||||
try {
|
||||
launcher.run();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e)
|
||||
{
|
||||
System.out.println("Generic exception occurred"+e.getMessage());
|
||||
}
|
||||
}).start();
|
||||
|
||||
@@ -250,11 +251,8 @@ public class ServerLauncher {
|
||||
* Game creation: TCP/RMI servers send the game model to all players.
|
||||
* Game execution: repeatedly calls doFirstEvent() to process the events in the actionQueue.
|
||||
* @throws InterruptedException if the TCP server thread is interrupted
|
||||
* @throws RemoteException if an RMI error occurs
|
||||
*/
|
||||
public void run() throws InterruptedException, RemoteException {
|
||||
|
||||
// Game execution
|
||||
public void run() {
|
||||
while (true) {
|
||||
try{
|
||||
this.doFirstEvent();
|
||||
@@ -267,9 +265,6 @@ public class ServerLauncher {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
catch(RemoteException e){
|
||||
System.out.println("Exception:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,20 +90,23 @@ public class TUI implements IView {
|
||||
*/
|
||||
@Override
|
||||
public void render() {
|
||||
if(model.currentState.getGameStage().equals(GameStages.TOTEM_CHOICE))
|
||||
if(model != null)
|
||||
{
|
||||
renderTotems();
|
||||
if(model.currentState.getGameStage().equals(GameStages.TOTEM_CHOICE))
|
||||
{
|
||||
renderTotems();
|
||||
}
|
||||
else if(model.currentState.getGameStage().equals(GameStages.ENDED))
|
||||
{
|
||||
//renderStanding
|
||||
renderBoard();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderBoard();
|
||||
}
|
||||
System.out.println("\nYOUR ACTION:");
|
||||
}
|
||||
else if(model.currentState.getGameStage().equals(GameStages.ENDED))
|
||||
{
|
||||
//renderStanding
|
||||
renderBoard();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderBoard();
|
||||
}
|
||||
System.out.println("\nYOUR ACTION:");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,14 +158,13 @@ public class TUI implements IView {
|
||||
public void renderTotems() {
|
||||
clearTerminal();
|
||||
var table = new AsciiTable(BorderStyle.ROUNDED, model.availableTotems.size());
|
||||
List<String> lines = model.availableTotems.stream().map(Totems::toString).toList();
|
||||
int i=0;
|
||||
for(String line : lines)
|
||||
List<String> lines =new ArrayList<>();
|
||||
for(int i=0;i<model.availableTotems.size();i++)
|
||||
{
|
||||
line = (i++) +". "+ line;
|
||||
lines.add(i+"."+model.availableTotems.get(i));
|
||||
}
|
||||
table.addRow(lines);
|
||||
System.out.println(model.currentState+"\nTOTEMS AVAILABLE:\n"+table.build());
|
||||
System.out.println(model.currentState+"\nTOTEMS AVAILABLE:\n"+table.build()+"\nPress 9 and then write the position");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +227,6 @@ public class TUI implements IView {
|
||||
table.addRow(List.of("6-PickOptionalBuilding(pos)", ""));
|
||||
table.addRow(List.of("7-NoOptional", ""));
|
||||
table.addRow(List.of("8-SkipTurn", ""));
|
||||
table.addRow(List.of("9-TotemChoice(pos)", ""));
|
||||
return table.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
package it.polimi.ingsw.gc14.Controller;
|
||||
|
||||
import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Model.Player;
|
||||
import it.polimi.ingsw.gc14.Network.IClient;
|
||||
import it.polimi.ingsw.gc14.View.IView;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientControllerTest {
|
||||
|
||||
private FakeView view;
|
||||
private FakeClient client;
|
||||
private ClientController controller;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
view = new FakeView();
|
||||
client = new FakeClient();
|
||||
controller = new ClientController(view);
|
||||
controller.setClient(client);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructorInitialization() {
|
||||
assertSame(view, controller.view);
|
||||
assertNotNull(controller.localController);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetModelUpdatesLocalControllerAndView() {
|
||||
Game game = createGame();
|
||||
controller.setModel(game);
|
||||
|
||||
assertSame(game, controller.localController.getModel());
|
||||
assertSame(game, view.model);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOnError() {
|
||||
controller.onError("Errore di test");
|
||||
assertEquals("Errore di test", view.lastError);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetClientDelegatesAction() {
|
||||
FakeClient newClient = new FakeClient();
|
||||
controller.setClient(newClient);
|
||||
|
||||
Game game = createGame();
|
||||
controller.setModel(game);
|
||||
|
||||
String current = game.getCurrentState().getCurrentPlayer().getUserName();
|
||||
controller.drawUpperTribeCard(current, 0);
|
||||
|
||||
assertEquals("drawUpperTribeCard", newClient.lastMethodCalled);
|
||||
assertEquals(current, newClient.lastUsername);
|
||||
assertEquals(0, newClient.lastPos);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDrawUpperTribeCardDelegatesCorrectly() {
|
||||
Game game = createGame();
|
||||
controller.setModel(game);
|
||||
|
||||
String current = game.getCurrentState().getCurrentPlayer().getUserName();
|
||||
controller.drawUpperTribeCard(current, 0);
|
||||
|
||||
assertEquals("drawUpperTribeCard", client.lastMethodCalled);
|
||||
assertEquals(current, client.lastUsername);
|
||||
assertEquals(0, client.lastPos);
|
||||
assertNull(view.lastError);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDrawUpperTribeCardWrongPlayerShowsError() {
|
||||
Game game = createGame();
|
||||
controller.setModel(game);
|
||||
|
||||
String current = game.getCurrentState().getCurrentPlayer().getUserName();
|
||||
String wrong = current.equals("p1") ? "p2" : "p1";
|
||||
controller.drawUpperTribeCard(wrong, 0);
|
||||
|
||||
assertEquals("It's not your turn!", view.lastError);
|
||||
assertNull(client.lastMethodCalled);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSlotChoiceDelegatesCorrectly() {
|
||||
Game game = createGame();
|
||||
controller.setModel(game);
|
||||
|
||||
String current = game.getCurrentState().getCurrentPlayer().getUserName();
|
||||
controller.slotChoice(current, 1);
|
||||
|
||||
assertEquals("slotChoice", client.lastMethodCalled);
|
||||
assertEquals(current, client.lastUsername);
|
||||
assertEquals(1, client.lastPos);
|
||||
assertNull(view.lastError);
|
||||
}
|
||||
|
||||
|
||||
private Game createGame() {
|
||||
Game game = new Game(2);
|
||||
game.addPlayer(new Player("p1"));
|
||||
game.addPlayer(new Player("p2"));
|
||||
return game;
|
||||
}
|
||||
|
||||
|
||||
private static class FakeView implements IView {
|
||||
Game model;
|
||||
String lastError;
|
||||
|
||||
@Override public void setModel(Game game) { this.model = game; }
|
||||
@Override public void render() {}
|
||||
@Override public void showMessage(String message) {}
|
||||
@Override public void showError(String message) { this.lastError = message; }
|
||||
}
|
||||
|
||||
private static class FakeClient implements IClient {
|
||||
String lastMethodCalled;
|
||||
String lastUsername;
|
||||
int lastPos;
|
||||
|
||||
@Override public boolean connect(String username, int preferredInt) { return true; }
|
||||
@Override public void drawUpperTribeCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawUpperTribeCard"; lastUsername = u; lastPos = pos; }
|
||||
@Override public void drawLowerTribeCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawLowerTribeCard"; lastUsername = u; lastPos = pos; }
|
||||
@Override public void drawUpperBuildingCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawUpperBuildingCard"; lastUsername = u; lastPos = pos; }
|
||||
@Override public void drawLowerBuildingCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawLowerBuildingCard"; lastUsername = u; lastPos = pos; }
|
||||
@Override public void skipTurn(String u) throws RemoteException { lastMethodCalled = "skipTurn"; lastUsername = u; }
|
||||
@Override public void pickOptionalTribeCard(String u, int pos) throws RemoteException { lastMethodCalled = "pickOptionalTribeCard"; lastUsername = u; lastPos = pos; }
|
||||
@Override public void pickOptionalBuildingCard(String u, int pos) throws RemoteException { lastMethodCalled = "pickOptionalBuildingCard"; lastUsername = u; lastPos = pos; }
|
||||
@Override public void noOptionalCard(String u) throws RemoteException { lastMethodCalled = "noOptionalCard"; lastUsername = u; }
|
||||
@Override public void slotChoice(String u, int pos) throws RemoteException { lastMethodCalled = "slotChoice"; lastUsername = u; lastPos = pos; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user