Merge branch 'main' of https://github.com/rubenpirreram/ing-sw-2026-pirrera-radice-pagani-pellegrino into javadoc-fixes
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
package it.polimi.ingsw.gc14;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class ClientLauncher {
|
||||
public void main() {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
System.out.println("Selezionare nome utente: ");
|
||||
String username = scanner.next();
|
||||
System.out.println(username);
|
||||
|
||||
System.out.println("Selezionare numero di giocatori desiderato: ");
|
||||
int proposedNumPlayers = scanner.nextInt();
|
||||
System.out.println(proposedNumPlayers);
|
||||
|
||||
System.out.println("Selezionare RMI[0] o TCP[1]: ");
|
||||
int networkType = scanner.nextInt();
|
||||
System.out.println(networkType);
|
||||
|
||||
scanner.close(); // chiudi solo alla fine
|
||||
|
||||
if (networkType == 0) {
|
||||
return;
|
||||
} else if (networkType == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package it.polimi.ingsw.gc14;
|
||||
import it.polimi.ingsw.gc14.Controller.ClientController;
|
||||
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
|
||||
import it.polimi.ingsw.gc14.View.IView;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
public class ClientLauncherTUI {
|
||||
public void main() throws InterruptedException {
|
||||
ClientController controller = new ClientController();
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
System.out.println("Selezionare nome utente: ");
|
||||
String username = scanner.next();
|
||||
System.out.println(username);
|
||||
|
||||
System.out.println("Selezionare numero di giocatori desiderato: ");
|
||||
int proposedNumPlayers = scanner.nextInt();
|
||||
System.out.println(proposedNumPlayers);
|
||||
|
||||
System.out.println("Selezionare RMI[0] o TCP[1]: ");
|
||||
int networkType = scanner.nextInt();
|
||||
System.out.println(networkType);
|
||||
|
||||
scanner.close();
|
||||
|
||||
if (networkType == 0) {
|
||||
RMIClient client = new RMIClient("localhost", 1099);
|
||||
if (client.connect(username, proposedNumPlayers, controller)) {
|
||||
System.out.println("Succesfully connected to RMI server\n\n");
|
||||
} else {
|
||||
System.out.println("RMI connection refused\n\n");
|
||||
}
|
||||
|
||||
while(true) {
|
||||
System.out.flush();
|
||||
if (controller.localModel!=null) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
System.out.println("Model set\n\n");
|
||||
|
||||
|
||||
|
||||
|
||||
} else if (networkType == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import it.polimi.ingsw.gc14.View.IView;
|
||||
|
||||
public class ClientController {
|
||||
|
||||
private Game localModel;
|
||||
public Game localModel;
|
||||
public GameController localController;
|
||||
public final IView view;
|
||||
public IView view=null;
|
||||
|
||||
public ClientController(IView view,Game localModel) {
|
||||
this.view = view;
|
||||
@@ -16,12 +16,18 @@ public class ClientController {
|
||||
this.localController = new GameController(localModel);
|
||||
}
|
||||
|
||||
public ClientController() {
|
||||
this.localController = new GameController(localModel);
|
||||
}
|
||||
|
||||
public void setModel(Game model) {
|
||||
this.localModel = model;
|
||||
localController.setModel(model);
|
||||
localModel.addObserver((Observer) view); // registra la view come observer
|
||||
// localModel.addObserver((Observer) view); // registra la view come observer
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void onError(String message) {
|
||||
view.showError(message);
|
||||
}
|
||||
|
||||
@@ -111,9 +111,9 @@ public class Board implements Serializable {
|
||||
ArrayList<BuildingCard> buildingDeck = new ArrayList<>(DecksCreator.loadBuildingDeckByEra(1));
|
||||
Collections.shuffle(buildingDeck);
|
||||
if(nTotem==2)
|
||||
upperListBuilding= buildingDeck.subList(0,1);
|
||||
upperListBuilding = new ArrayList<>(buildingDeck.subList(0,1));
|
||||
else
|
||||
upperListBuilding= buildingDeck.subList(0,2);
|
||||
upperListBuilding = new ArrayList<>(buildingDeck.subList(0,2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package it.polimi.ingsw.gc14.Network;
|
||||
|
||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||
import javafx.event.Event;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -12,9 +11,23 @@ public abstract class NetworkEvent implements Serializable {
|
||||
}
|
||||
protected EventType eventType;
|
||||
public EventType getEventType() {return eventType;}
|
||||
protected NetworkEvent(String username, EventType eventType) {
|
||||
protected boolean isError;
|
||||
public boolean getIsError() {return isError;}
|
||||
public void setIsError(boolean isError) {this.isError = isError;}
|
||||
|
||||
protected NetworkEvent(String username, EventType eventType, boolean isError) {
|
||||
this.username = username;
|
||||
this.eventType = eventType;
|
||||
this.isError = isError;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(isError) {
|
||||
return ("ERROR: action " + eventType.toString());
|
||||
} else {
|
||||
return ("ACTION: action " + eventType.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean apply(GameController gameController);
|
||||
|
||||
@@ -13,7 +13,7 @@ public class AddPlayer extends NetworkEvent implements Serializable {
|
||||
return proposedNPlayer;
|
||||
}
|
||||
public AddPlayer(String username, int proposedNPlayer) {
|
||||
super(username, EventType.ADD_PLAYER);
|
||||
super(username, EventType.ADD_PLAYER, false);
|
||||
this.proposedNPlayer = proposedNPlayer;
|
||||
}
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,7 @@ public class DrawLowerBuildingCard extends NetworkEvent implements Serializable
|
||||
private int pos;
|
||||
|
||||
public DrawLowerBuildingCard(String username, int pos){
|
||||
super(username, EventType.DRAW_LOWER_BUILD);
|
||||
super(username, EventType.DRAW_LOWER_BUILD, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public class DrawLowerTribeCard extends NetworkEvent implements Serializable{
|
||||
private int pos;
|
||||
|
||||
public DrawLowerTribeCard(String username, int pos){
|
||||
super(username, EventType.DRAW_LOWER_TRIBE);
|
||||
super(username, EventType.DRAW_LOWER_TRIBE, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public class DrawUpperBuildingCard extends NetworkEvent implements Serializable
|
||||
private int pos;
|
||||
|
||||
public DrawUpperBuildingCard(String username, int pos){
|
||||
super(username, EventType.DRAW_UPPER_BUILD);
|
||||
super(username, EventType.DRAW_UPPER_BUILD, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public class DrawUpperTribeCard extends NetworkEvent implements Serializable{
|
||||
private int pos;
|
||||
|
||||
public DrawUpperTribeCard(String username, int pos){
|
||||
super(username, EventType.DRAW_UPPER_TRIBE);
|
||||
super(username, EventType.DRAW_UPPER_TRIBE, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ public class PickOptionalBuildingCard extends NetworkEvent implements Serializa
|
||||
private int pos;
|
||||
|
||||
public PickOptionalBuildingCard(String username, int pos){
|
||||
super(username, EventType.PICK_OPTIONAL_BUILD);
|
||||
super(username, EventType.PICK_OPTIONAL_BUILD, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public class PickOptionalTribeCard extends NetworkEvent implements Serializable
|
||||
private int pos;
|
||||
|
||||
public PickOptionalTribeCard(String username, int pos){
|
||||
super(username, EventType.PICK_OPTIONAL_TRIBE);
|
||||
super(username, EventType.PICK_OPTIONAL_TRIBE, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public class SlotChoice extends NetworkEvent implements Serializable {
|
||||
private int pos;
|
||||
|
||||
public SlotChoice(String username, int pos) {
|
||||
super(username, EventType.SLOT_CHOICE);
|
||||
super(username, EventType.SLOT_CHOICE, false);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,31 +5,57 @@ import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCallback {
|
||||
|
||||
/**
|
||||
* RMI client callback implementation of {@link IClientCallback}.
|
||||
* Receives notifications from the server and updates the client game model.
|
||||
*/
|
||||
public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCallback, Serializable {
|
||||
|
||||
/** The client controller used to apply events and update the model */
|
||||
private final ClientController clientController;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
* @param clientController the client controller
|
||||
* @throws RemoteException if any RMI error occurs
|
||||
*/
|
||||
public ClientCallbackImpl(ClientController clientController) throws RemoteException {
|
||||
this.clientController = clientController;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the server when the game is initialized.
|
||||
* Sets the client game model in the {@link ClientController}.
|
||||
* @param model the initialized {@link Game} model
|
||||
* @throws RemoteException if any RMI error occurs
|
||||
*/
|
||||
@Override
|
||||
public void onGameInit(Game model) throws RemoteException {
|
||||
clientController.setModel(model); // setta il model
|
||||
clientController.setModel(model);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the server when an action has been accepted.
|
||||
* If the event contains an error, it is printed to the console.
|
||||
* Otherwise, the event is applied to the local model.
|
||||
* @param event the {@link NetworkEvent} sent by the server
|
||||
* @throws RemoteException if any RMI error occurs
|
||||
*/
|
||||
@Override
|
||||
public void onAction(NetworkEvent event) throws RemoteException {
|
||||
event.apply(clientController.localController); // delega tutto al controller
|
||||
//clientController.view.update(); TODO
|
||||
if(event.getIsError()) {
|
||||
System.out.println(event.toString());
|
||||
} else {
|
||||
event.apply(clientController.localController);
|
||||
//clientController.view.update(); TODO
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String message) throws RemoteException {
|
||||
clientController.onError(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,43 +1,55 @@
|
||||
package it.polimi.ingsw.gc14.Network.RMI.Client;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
|
||||
import it.polimi.ingsw.gc14.Controller.ClientController;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
||||
import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer;
|
||||
|
||||
public class RMIClient {
|
||||
/**
|
||||
* Client RMI. Uses the methods exposed by the server RMI.
|
||||
*/
|
||||
public class RMIClient {
|
||||
|
||||
/** The host address of the RMI server */
|
||||
private final String host;
|
||||
|
||||
/** The port of the RMI server */
|
||||
private final int port;
|
||||
|
||||
/** The remote stub used to call methods on the server */
|
||||
private IGameServer stub;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
* @param host the host address of the RMI server
|
||||
* @param port the port of the RMI server
|
||||
*/
|
||||
public RMIClient(String host, int port) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
|
||||
public boolean connect(String username,int preferredInt,ClientController clientController) {
|
||||
// 1. Connettiti al registry
|
||||
/**
|
||||
* Connects to the RMI server and attempts to join the game.
|
||||
* Looks up the RMI registry to retrieve the {@link IGameServer} stub.
|
||||
* Then, creates a {@link ClientCallbackImpl} and calls {@link RMIServer#joinGame(String, int, IClientCallback)}.
|
||||
* @param username the player's username
|
||||
* @param preferredInt the desired number of players
|
||||
* @param clientController the client controller used to create the callback
|
||||
* @return true if the player successfully joined the game, false otherwise
|
||||
*/
|
||||
public boolean connect(String username,int preferredInt, ClientController clientController) {
|
||||
try {
|
||||
Registry registry = LocateRegistry.getRegistry(host, port);
|
||||
|
||||
// 2. Prendi lo stub del server
|
||||
this.stub = (IGameServer) registry.lookup("RMIGameServer");
|
||||
|
||||
// 3. Crea il callback e registralo
|
||||
ClientCallbackImpl callback = new ClientCallbackImpl(clientController);
|
||||
|
||||
if (!stub.joinGame(username,preferredInt, callback))
|
||||
{
|
||||
stub = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return stub.joinGame(username, preferredInt, callback);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -46,8 +58,12 @@ public class RMIClient {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void doEvent(NetworkEvent event) throws Exception {
|
||||
/**
|
||||
* Sends a {@link NetworkEvent} to the server.
|
||||
* @param event the event to send
|
||||
* @throws RemoteException if any RMI error occurs
|
||||
*/
|
||||
public void doEvent(NetworkEvent event) throws RemoteException {
|
||||
stub.doEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ package it.polimi.ingsw.gc14.Network.RMI.Common;
|
||||
import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.*;
|
||||
|
||||
public interface IClientCallback extends Remote {
|
||||
public interface IClientCallback extends Remote, Serializable {
|
||||
void onGameInit(Game model) throws RemoteException;
|
||||
void onAction(NetworkEvent action) throws RemoteException;
|
||||
void onError(String message) throws RemoteException;
|
||||
}
|
||||
@@ -15,19 +15,47 @@ import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
import java.rmi.*;
|
||||
|
||||
public class RMIServer implements IGameServer {
|
||||
|
||||
/**
|
||||
* Server RMI. Exposes a method to join the game and one to execute an event.
|
||||
*/
|
||||
public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
|
||||
/** Server game's controller */
|
||||
private GameController controller;
|
||||
|
||||
/** Server game's model */
|
||||
private Game model;
|
||||
|
||||
/** RMI registry */
|
||||
private Registry registry;
|
||||
|
||||
/** RMI port */
|
||||
private int nPort;
|
||||
|
||||
/** Map containing the associations between a player's username and its callback */
|
||||
private final Map<String, IClientCallback> clients = new ConcurrentHashMap<>();
|
||||
|
||||
/** Queue containing the events to be applied to the game model */
|
||||
BlockingQueue<NetworkEvent> actionQueue;
|
||||
|
||||
/**
|
||||
* List containing the usernames of joined players.
|
||||
* {@link LimitedList}'s limit defines at which size the list calls its action. The limit can be set using {@link LimitedList#setLimit(int)}.
|
||||
*/
|
||||
private LimitedList<String> playerList;
|
||||
|
||||
// Costruttore
|
||||
|
||||
/**
|
||||
* Class constructor that initializes the attributes.
|
||||
* @param controller The game controller
|
||||
* @param nPort The RMI port
|
||||
* @param actionQueue The action queue
|
||||
* @param playerList The player's usernames list
|
||||
* @throws RemoteException if an RMI error occurs
|
||||
*/
|
||||
public RMIServer(GameController controller, int nPort, BlockingQueue<NetworkEvent> actionQueue,LimitedList<String> playerList) throws RemoteException {
|
||||
this.controller = controller;
|
||||
this.nPort = nPort;
|
||||
@@ -37,67 +65,85 @@ public class RMIServer implements IGameServer {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Metodi esposti RMI
|
||||
public void setController (GameController controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
// RMI's exposed methods
|
||||
/**
|
||||
* Allows a player to join the game.
|
||||
* If the desired number of player is invalid, the request is rejected.
|
||||
* If this is the first player, a new game model is created and passed to the controller. Additionally, the playerList's limit is set.
|
||||
* Then, if the controller successfully adds the player, the username is added to {@link #playerList} and {@link #clients}.
|
||||
* @param username The player's name
|
||||
* @param preferredInt The desired number of players
|
||||
* @param callback The client's callback interface
|
||||
* @return true if the player successfully joined the game, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean joinGame(String username, int preferredInt,IClientCallback callback) {
|
||||
public boolean joinGame(String username, int preferredInt, IClientCallback callback) {
|
||||
if (preferredInt<2 || preferredInt>5) {
|
||||
return false;
|
||||
}
|
||||
synchronized (controller) {
|
||||
if(playerList.size()==0 && (preferredInt<2||preferredInt>5))
|
||||
return false;
|
||||
if(playerList.isEmpty()){
|
||||
model = new Game(preferredInt);
|
||||
controller.setModel(model);
|
||||
playerList.setLimit(preferredInt);
|
||||
}
|
||||
if (controller.addPlayer(username)) {
|
||||
if(playerList.size()==0)
|
||||
{
|
||||
Game game= new Game(preferredInt);
|
||||
controller.setModel(game);
|
||||
playerList.setLimit(preferredInt);
|
||||
}
|
||||
playerList.add(username);
|
||||
clients.put(username, callback);
|
||||
playerList.add(username);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Push an action in actionQueue.
|
||||
* @param action The desired actio
|
||||
* @return true if the action was successfully added, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean doEvent(NetworkEvent event) throws RemoteException {
|
||||
return actionQueue.offer(event);
|
||||
public boolean doEvent(NetworkEvent action) {
|
||||
return actionQueue.offer(action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Metodi interni del server
|
||||
// RMI's internal methods
|
||||
/**
|
||||
* Sends an action to all RMI clients.
|
||||
* @param action The desired action
|
||||
*/
|
||||
public void notifyAll(NetworkEvent action) throws RemoteException {
|
||||
for (IClientCallback cb : clients.values()) {
|
||||
cb.onAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a game model to all RMI clients.
|
||||
* @param model The desired model
|
||||
*/
|
||||
public void notifyAll(Game model) throws RemoteException {
|
||||
for (IClientCallback cb : clients.values()) {
|
||||
cb.onGameInit(model);
|
||||
}
|
||||
}
|
||||
public void notifyError(String username, String message) throws RemoteException {
|
||||
IClientCallback cb = clients.get(username);
|
||||
if (cb != null) cb.onError(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Metodi per avviare server RMI
|
||||
/**
|
||||
* Starts the RMI server.
|
||||
* @return true if the server starts successfully, false otherwise
|
||||
*/
|
||||
public boolean start() {
|
||||
try {
|
||||
registry = LocateRegistry.createRegistry(nPort);
|
||||
registry.rebind("RMIGameServer", this);
|
||||
System.out.println("RMI Server avviato sulla porta "+nPort);
|
||||
System.out.println("RMI Server started on port: "+nPort);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -105,6 +151,12 @@ public class RMIServer implements IGameServer {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stops the RMI server.
|
||||
* @return true if the server stops successfully, false otherwise
|
||||
*/
|
||||
public boolean stop() {
|
||||
try {
|
||||
registry.unbind("RMIGameServer");
|
||||
|
||||
@@ -1,70 +1,118 @@
|
||||
package it.polimi.ingsw.gc14.Network.TCP.Client;
|
||||
|
||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||
import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
public class TCPClient implements Serializable{
|
||||
Socket communicationSocket = null;
|
||||
/**
|
||||
* Client TCP. Sends and receives messages with the TCP server.
|
||||
*/
|
||||
public class TCPClient {
|
||||
|
||||
/** Socket TCP */
|
||||
Socket communicationSocket;
|
||||
|
||||
/** Input stream used receive objects from the server */
|
||||
ObjectInputStream socketReceive;
|
||||
|
||||
/** Output stream used to send objects to the server */
|
||||
ObjectOutputStream socketSend;
|
||||
|
||||
/** Client game's controller */
|
||||
GameController controller;
|
||||
|
||||
/** IP address of the server to connect to */
|
||||
String hostname;
|
||||
|
||||
/** TCP port */
|
||||
int port;
|
||||
|
||||
public TCPClient(GameController controller, String hostname, int port){
|
||||
|
||||
/**
|
||||
* Class constructor that initializes the attributes.
|
||||
* @param controller The game controller
|
||||
* @param hostname The IP address of the server
|
||||
* @param port The TCP port of the server
|
||||
*/
|
||||
public TCPClient(GameController controller, String hostname, int port) {
|
||||
this.controller = controller;
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public boolean start(String user, int players){
|
||||
try{
|
||||
|
||||
/**
|
||||
* Starts the TCP connection with the server.
|
||||
* Sends an {@link AddPlayer} event, if the server responds with {@code -1}, the connection is refused and the method returns {@code false}.
|
||||
* Otherwise, a listener thread is started.
|
||||
* @param user The username of the player
|
||||
* @param proposedNPlayers The desired number of players for the game
|
||||
* @return true if the connection is successful, false otherwise.
|
||||
*/
|
||||
public boolean start(String user, int proposedNPlayers) {
|
||||
try {
|
||||
communicationSocket = new Socket(hostname, port);
|
||||
socketSend = new ObjectOutputStream(communicationSocket.getOutputStream());
|
||||
socketReceive = new ObjectInputStream(communicationSocket.getInputStream());
|
||||
|
||||
socketSend.writeObject(new AddPlayer(user, players));
|
||||
if(communicationSocket.getInputStream().read() == -1){
|
||||
sendEvent(new AddPlayer(user, proposedNPlayers));
|
||||
if (communicationSocket.getInputStream().read() == -1) {
|
||||
System.out.println("Could not connect to server");
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
Thread listener = new Thread(() -> ReceiveMessage());
|
||||
} else {
|
||||
Thread listener = new Thread(() -> receiveMessage());
|
||||
listener.start();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(Exception e){
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceiveMessage(){
|
||||
while(true){
|
||||
try{
|
||||
((NetworkEvent)(socketReceive.readObject())).apply(controller);
|
||||
}
|
||||
catch(IOException e){
|
||||
|
||||
/**
|
||||
* Listens continuously for incoming objects from the server.
|
||||
* - If the received object is a {@link NetworkEvent} flagged as an error, it is printed.
|
||||
* - If the received object is a valid {@link NetworkEvent}, it is applied to the game controller.
|
||||
* - If the received object is a {@link Game} model, the controller's model is set.
|
||||
*/
|
||||
private void receiveMessage() {
|
||||
while (true) {
|
||||
try {
|
||||
Object read = socketReceive.readObject();
|
||||
if (read instanceof NetworkEvent event) { //TODO: avoid instanceof
|
||||
if (event.getIsError()) {
|
||||
System.out.println(event);
|
||||
} else {
|
||||
event.apply(controller);
|
||||
//clientController.view.update(); TODO
|
||||
}
|
||||
} else if (read instanceof Game model) {
|
||||
controller.setModel(model);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch(ClassNotFoundException e){
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendEvent(NetworkEvent event){
|
||||
try{
|
||||
|
||||
/**
|
||||
* Sends a {@link NetworkEvent} to the server.
|
||||
* @param event The NetworkEvent to send.
|
||||
*/
|
||||
private void sendEvent(NetworkEvent event) {
|
||||
try {
|
||||
socketSend.writeObject(event);
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +1,105 @@
|
||||
package it.polimi.ingsw.gc14.Network.TCP.Server;
|
||||
|
||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||
import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import it.polimi.ingsw.gc14.Network.EventType;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* Handles the TCP connection with a single client.
|
||||
* Each instance runs on a dedicated thread and is responsible for receiving {@link NetworkEvent} from its client and adding them
|
||||
* to the {@link #actionQueue}.
|
||||
* It is also responsible to send events and game model updates back to the client.
|
||||
*/
|
||||
public class ClientHandler implements Runnable {
|
||||
|
||||
/** The TCP socket */
|
||||
private Socket clientSocket;
|
||||
private TCPServer server;
|
||||
public ObjectInputStream in = null;
|
||||
public ObjectOutputStream out = null;
|
||||
|
||||
/** Input stream used to receive objects from the client */
|
||||
public ObjectInputStream in;
|
||||
|
||||
/** Output stream used to send objects to the client */
|
||||
public ObjectOutputStream out;
|
||||
|
||||
/**
|
||||
* Shared list of all client handlers.
|
||||
* This handler removes itself from the list when disconnected.
|
||||
*/
|
||||
List<ClientHandler> clientHandlers;
|
||||
|
||||
/** Queue containing the events to be applied to the game model */
|
||||
BlockingQueue<NetworkEvent> actionQueue;
|
||||
private EventType eventType;
|
||||
|
||||
public Socket getClientSocket() {
|
||||
return clientSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor that initializes the attributes.
|
||||
* @param clientSocket The socket representing the client's TCP connection
|
||||
* @param clientHandlers The shared list of all active client handlers
|
||||
* @param actionQueue The queue containing incoming events
|
||||
*/
|
||||
public ClientHandler(Socket clientSocket, List<ClientHandler> clientHandlers, BlockingQueue<NetworkEvent> actionQueue) {
|
||||
this.clientSocket = clientSocket;
|
||||
this.clientHandlers = clientHandlers;
|
||||
this.actionQueue = actionQueue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Listens for incoming {@link NetworkEvent}s from the client and adds them to the {@link #actionQueue}.
|
||||
* Upon disconnection, this handler removes itself from {@link #clientHandlers}.
|
||||
*/
|
||||
@Override
|
||||
public void run(){
|
||||
clientLoop();
|
||||
}
|
||||
|
||||
private void clientLoop(){
|
||||
try{
|
||||
NetworkEvent input = null;
|
||||
synchronized(in){
|
||||
in = new ObjectInputStream(clientSocket.getInputStream());
|
||||
public void run() {
|
||||
try {
|
||||
in = new ObjectInputStream(clientSocket.getInputStream());
|
||||
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
||||
while (true) {
|
||||
NetworkEvent event = (NetworkEvent) in.readObject();
|
||||
if (!actionQueue.add(event)) {
|
||||
System.out.println("Error inserting action into queue");
|
||||
}
|
||||
}
|
||||
while(true){
|
||||
try{
|
||||
input = (NetworkEvent) (in.readObject());
|
||||
if(actionQueue.add(input)){
|
||||
server.broadcastUpdate(input);
|
||||
}
|
||||
}
|
||||
catch(java.io.IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (ClassNotFoundException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
clientHandlers.remove(this);
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyEvent(NetworkEvent event){
|
||||
synchronized(out){
|
||||
try{
|
||||
|
||||
/**
|
||||
* Sends a {@link NetworkEvent} to the client.
|
||||
* @param event The network event to send to the client.
|
||||
*/
|
||||
public void notifyEvent(NetworkEvent event) {
|
||||
synchronized (out) {
|
||||
try {
|
||||
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
||||
out.writeObject(event);
|
||||
}
|
||||
catch(IOException e){
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyModel(Game game){
|
||||
synchronized(out){
|
||||
try{
|
||||
|
||||
/**
|
||||
* Sends the current game model to this client.
|
||||
* @param game The current state of the game to send to the client.
|
||||
*/
|
||||
public void notifyModel(Game game) {
|
||||
synchronized (out) {
|
||||
try {
|
||||
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
||||
out.writeObject(game);
|
||||
}
|
||||
catch(IOException e){
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package it.polimi.ingsw.gc14.Network.TCP.Server;
|
||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||
import it.polimi.ingsw.gc14.LimitedList;
|
||||
import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Network.EventType;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer;
|
||||
|
||||
@@ -12,71 +13,120 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
|
||||
/**
|
||||
* Server TCP. Accepts connections and manages all client handlers.
|
||||
*/
|
||||
public class TCPServer {
|
||||
int port = -1;
|
||||
int ConnectedPlayers = 0;
|
||||
ServerSocket serverTCP = null;
|
||||
GameController gameController;
|
||||
|
||||
/** TCP port */
|
||||
int port;
|
||||
|
||||
/** Number of currently connected clients */
|
||||
int ConnectedPlayers;
|
||||
|
||||
/** Socket TCP */
|
||||
ServerSocket socketTCP;
|
||||
|
||||
/** Server game's controller */
|
||||
GameController controller;
|
||||
|
||||
/** Queue containing the events to be applied to the game model */
|
||||
BlockingQueue<NetworkEvent> actionQueue;
|
||||
|
||||
/**
|
||||
* List containing the usernames of joined players.
|
||||
* {@link LimitedList}'s limit defines at which size the list calls its action. The limit can be set using {@link LimitedList#setLimit(int)}.
|
||||
*/
|
||||
private LimitedList<String> playerList;
|
||||
|
||||
/** List containing all client's handlers */
|
||||
private List<ClientHandler> clientHandlers;
|
||||
|
||||
|
||||
|
||||
private int getConnectedPlayers(){
|
||||
return ConnectedPlayers;
|
||||
/**
|
||||
* Class constructor that initializes the attributes.
|
||||
* @param controller The game controller
|
||||
* @param port The TCP port
|
||||
* @param actionQueue The action queue
|
||||
* @param playerList The player's usernames list
|
||||
*/
|
||||
public TCPServer(GameController controller, int port, BlockingQueue<NetworkEvent> actionQueue, LimitedList<String> playerList){
|
||||
this.port = port;
|
||||
this.ConnectedPlayers = 0;
|
||||
this.socketTCP = null;
|
||||
this.controller = controller;
|
||||
this.actionQueue = actionQueue;
|
||||
this.playerList = playerList;
|
||||
this.clientHandlers = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts the TCP server.
|
||||
* If the first event is not AddPlayer, the request is rejected.
|
||||
* If the desired number of player is invalid, the request is rejected.
|
||||
*
|
||||
* If this is the first player to connect, a new game model is created and passed to the controller. Additionally, the playerList's limit is set.
|
||||
* If the controller successfully adds the player, the username is added to {@link #playerList} and the handler is added to {@link #clientHandlers}.
|
||||
*
|
||||
* If any error occurs, the server sends -1 back to the client. Otherwise, it sends 1.
|
||||
*/
|
||||
public void start(){
|
||||
clientHandlers = new ArrayList<>();
|
||||
|
||||
try{
|
||||
serverTCP = new ServerSocket(port);
|
||||
socketTCP = new ServerSocket(port);
|
||||
}
|
||||
catch (IOException e){
|
||||
System.out.println("Could not listen on port: " + port);
|
||||
System.out.println("Could not start the server TCP on port: " + port);
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
System.out.println("Listening on port: " + port);
|
||||
System.out.println("Server TCP started on port: " + port);
|
||||
Socket clientSocket;
|
||||
|
||||
while(true){
|
||||
Socket clientSocket = null;
|
||||
|
||||
try{
|
||||
clientSocket = serverTCP.accept();
|
||||
clientSocket = socketTCP.accept();
|
||||
ObjectInputStream clientSocketObj = new ObjectInputStream(clientSocket.getInputStream());
|
||||
NetworkEvent event = (NetworkEvent) clientSocketObj.readObject();
|
||||
|
||||
synchronized (gameController){
|
||||
if(!(event instanceof AddPlayer) || (gameController.getModel() != null && gameController.getModel().getCurrentPlayerNumber() >= gameController.getModel().getNPlayers())){
|
||||
clientSocket.getOutputStream().write((int)(-1));
|
||||
if(!(event.getEventType() == EventType.ADD_PLAYER)){
|
||||
clientSocket.getOutputStream().write((int)(-1));
|
||||
clientSocket.close();
|
||||
System.out.println("Invalid parameters. Connection terminated.\n");
|
||||
}
|
||||
else{
|
||||
AddPlayer eventAddPlayer = (AddPlayer) event;
|
||||
if (eventAddPlayer.getProposedNPlayer() < 2 || eventAddPlayer.getProposedNPlayer() > 5) {
|
||||
clientSocket.getOutputStream().write((int) (-1));
|
||||
clientSocket.close();
|
||||
System.out.println("Invalid parameters. Connection terminated.\n");
|
||||
}
|
||||
else{
|
||||
synchronized (gameController) {
|
||||
AddPlayer addPlayer = (AddPlayer) event;
|
||||
if(playerList.isEmpty() && (addPlayer.getProposedNPlayer() < 2 || addPlayer.getProposedNPlayer() > 5)){
|
||||
clientSocket.getOutputStream().write((int)(-1));
|
||||
clientSocket.close();
|
||||
System.out.println("Invalid parameters. Connection terminated.\n");
|
||||
}
|
||||
else if(gameController.addPlayer(addPlayer.getUsername())){
|
||||
if(playerList.isEmpty()){
|
||||
Game game = new Game(addPlayer.getProposedNPlayer());
|
||||
gameController.setModel(game);
|
||||
playerList.setLimit(addPlayer.getProposedNPlayer());
|
||||
}
|
||||
playerList.add(addPlayer.getUsername());
|
||||
clientSocket.getOutputStream().write((int)(1));
|
||||
}
|
||||
synchronized (controller) {
|
||||
if (playerList.isEmpty()){
|
||||
Game model = new Game(eventAddPlayer.getProposedNPlayer());
|
||||
controller.setModel(model);
|
||||
playerList.setLimit(eventAddPlayer.getProposedNPlayer());
|
||||
}
|
||||
if (controller.addPlayer(eventAddPlayer.getUsername())) {
|
||||
playerList.add(eventAddPlayer.getUsername());
|
||||
clientSocket.getOutputStream().write((int) (1));
|
||||
|
||||
System.out.println("Accepted player: " + eventAddPlayer.getUsername());
|
||||
ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, actionQueue);
|
||||
clientHandlers.add(clientHandler);
|
||||
ConnectedPlayers++;
|
||||
|
||||
Thread t = new Thread(clientHandler);
|
||||
t.start();
|
||||
} else {
|
||||
clientSocket.getOutputStream().write((int) (-1));
|
||||
clientSocket.close();
|
||||
System.out.println("Player could not be added. Connection terminated.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
// gestione di ADD_PLAYER
|
||||
}
|
||||
catch(IOException e){
|
||||
e.printStackTrace();
|
||||
@@ -84,45 +134,18 @@ public class TCPServer {
|
||||
catch(ClassNotFoundException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
System.out.println("Accepted player: " + gameController.getModel().getPlayerByUsername(clientSocket.getInetAddress().toString()));
|
||||
|
||||
ConnectedPlayers++;
|
||||
ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, actionQueue);
|
||||
clientHandlers.add(clientHandler);
|
||||
|
||||
//Sending model to clients
|
||||
if(ConnectedPlayers == gameController.getModel().getNPlayers()){
|
||||
for (ClientHandler handler : clientHandlers) {
|
||||
try {
|
||||
synchronized(handler.out){
|
||||
ObjectOutputStream socketTx = new ObjectOutputStream(handler.getClientSocket().getOutputStream());
|
||||
socketTx.writeObject(gameController.getModel());
|
||||
}
|
||||
}
|
||||
catch(IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread t = new Thread(clientHandler);
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
||||
public TCPServer(GameController gameController, int port, BlockingQueue<NetworkEvent> actionQueue, LimitedList<String> players){
|
||||
this.port = port;
|
||||
this.gameController = gameController;
|
||||
this.actionQueue = actionQueue;
|
||||
this.playerList = players;
|
||||
}
|
||||
|
||||
public void broadcastUpdate(NetworkEvent event){
|
||||
/** Sends an action to all TCP clients */
|
||||
public void notifyAll(NetworkEvent event){
|
||||
clientHandlers.forEach((x) -> x.notifyEvent(event));
|
||||
}
|
||||
|
||||
public void broadcastModel(Game model){
|
||||
|
||||
/** Sends a game model to all TCP clients */
|
||||
public void notifyAll(Game model){
|
||||
clientHandlers.forEach((x) -> x.notifyModel(model));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,58 @@ import java.rmi.RemoteException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
|
||||
/**
|
||||
* Main server launcher that handles both TCP and RMI connections.
|
||||
* The workflow is divided into two parts: game creation and game execution.
|
||||
*
|
||||
* The process flow for game creation is as follows:
|
||||
* - The first client (TCP/RMI) requests to join the game by providing a username and the desired number of players
|
||||
* - The TCP/RMI server checks {@link #playerList} and, if it is empty, sets the number of players according to the first user's request using {@link LimitedList#setLimit(int)}
|
||||
* - The TCP/RMI server creates the {@link Game} with the requested number of players and adds the player to {@link #playerList}
|
||||
* - Other players request to join the game (their requested number of players is ignored)
|
||||
* - When the number of players in {@link #playerList} reaches the {@link LimitedList}'s limit, the list calls {@link #run()}
|
||||
* - All players are notified of the {@link Game}
|
||||
*
|
||||
* The process flow for game execution is as follows:
|
||||
* - The TCP/RMI server receives a {@link NetworkEvent} from a client and adds it to the {@link #actionQueue}
|
||||
* - The {@link #run()} method repeatedly calls {@link #doFirstEvent()}, which takes the first event in the {@link #actionQueue} and tries to apply it
|
||||
* - If the event cannot be successfully applied to the model, its {@code isError} flag is set to {@code true}
|
||||
* - All players are notified of the event
|
||||
*/
|
||||
public class ServerLauncher {
|
||||
|
||||
/**
|
||||
* Queue containinetworkTypeng the events to be applied to the game model.
|
||||
* Thread safe by design.
|
||||
*/
|
||||
BlockingQueue<NetworkEvent> actionQueue;
|
||||
|
||||
/** Game controller. Used to apply events */
|
||||
GameController gameController;
|
||||
|
||||
/** Server RMI. Handles RMI clients */
|
||||
RMIServer serverRMI;
|
||||
|
||||
/** Server TCP. Handles TCP clients */
|
||||
TCPServer serverTCP;
|
||||
static LimitedList<String> players;
|
||||
|
||||
|
||||
/**
|
||||
* List containing the usernames of joined players.
|
||||
* {@link LimitedList}'s limit defines at which size the list calls its action
|
||||
* Both the limit and the action can be set using {@link LimitedList#setLimit(int)} and {@link LimitedList#setAction(Runnable)}
|
||||
* The limit is set by the first player joining the game. The action consists in calling {@link #run()}
|
||||
*/
|
||||
static LimitedList<String> playerList;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor that initializes the attributes.
|
||||
* @param actionQueue The queue containing the events
|
||||
* @param gameController The game controller
|
||||
* @param serverRMI The server RMI
|
||||
* @param serverTCP The server TCP
|
||||
*/
|
||||
public ServerLauncher(BlockingQueue<NetworkEvent> actionQueue, GameController gameController, RMIServer serverRMI, TCPServer serverTCP) {
|
||||
this.actionQueue = actionQueue;
|
||||
this.serverRMI = serverRMI;
|
||||
@@ -29,56 +71,77 @@ public class ServerLauncher {
|
||||
this.serverTCP = serverTCP;
|
||||
}
|
||||
|
||||
public boolean doFirstEven() throws InterruptedException, RemoteException {
|
||||
|
||||
/**
|
||||
* Takes the first event in the actionQueue and attempts to apply it to the game controller.
|
||||
* If the event cannot be applied, its isError flag is set to true; otherwise, it is set to false.
|
||||
* 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 {
|
||||
NetworkEvent event = actionQueue.take();
|
||||
if(event.apply(gameController)) {
|
||||
serverRMI.notifyAll(event);
|
||||
serverTCP.broadcastUpdate(event);
|
||||
return true;
|
||||
} else {
|
||||
serverRMI.notifyError(event.getUsername(), "Mossa non valida"); // TODO Converrebbe mettere in network event un booleano che dice se è stato accettato e fare una notifyAll anche per errori
|
||||
//serverTCP // TODO non esiste un notify error (guarda sopra)
|
||||
return false;
|
||||
}
|
||||
event.setIsError(!event.apply(gameController));
|
||||
|
||||
serverRMI.notifyAll(event);
|
||||
serverTCP.notifyAll(event);
|
||||
|
||||
return !event.getIsError();
|
||||
}
|
||||
|
||||
|
||||
public static void main() throws RemoteException, InterruptedException {
|
||||
// TODO
|
||||
// Deve avere una coda con gli eventi.
|
||||
// Il server RMI e il server TCP quando ricevono un doEvent devono aggiungere l'evento alla coda condivisa
|
||||
// Questa classe esegue gli eventi nella coda e chiama il notify all e notify error sia RMI che TCP
|
||||
|
||||
players = new LimitedList<>(5, ()->{});
|
||||
/**
|
||||
* The first method executed when the server program is launched.
|
||||
* It creates all the objects needed: playerList, actionQueue, gameController, serverRMI, serverTCP, launcher.
|
||||
* Then sets the playerList's action to execute launcher.run() and starts the TCP/RMI servers.
|
||||
* Note: the model is initialized and set in the controller in TCP/RMI servers when the first user decides the number of players.
|
||||
*
|
||||
* @throws InterruptedException if this exception is issued by run method
|
||||
* @throws RemoteException if this exception is issued by run method
|
||||
*/
|
||||
public static void main(String[] args) throws InterruptedException, RemoteException {
|
||||
playerList = new LimitedList<>(5, ()->{});
|
||||
BlockingQueue<NetworkEvent> actionQueue = new LinkedBlockingQueue<>();
|
||||
GameController gameController = new GameController();
|
||||
RMIServer serverRMI = new RMIServer(gameController, 1099, actionQueue, players);
|
||||
TCPServer serverTCP = new TCPServer(gameController, 8080, actionQueue, players);
|
||||
RMIServer serverRMI = new RMIServer(gameController, 1099, actionQueue, playerList);
|
||||
TCPServer serverTCP = new TCPServer(gameController, 8080, actionQueue, playerList);
|
||||
ServerLauncher launcher = new ServerLauncher(actionQueue, gameController, serverRMI, serverTCP);
|
||||
|
||||
players.setAction(()->{
|
||||
try {
|
||||
launcher.run();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
playerList.setAction(()->{
|
||||
new Thread(()->{
|
||||
try {
|
||||
launcher.run();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
serverRMI.start();
|
||||
new Thread(()->{serverTCP.start();}).start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and executes the game.
|
||||
* 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 creation
|
||||
System.out.println("\n\nNotifying model");
|
||||
serverRMI.notifyAll(gameController.getModel());
|
||||
serverTCP.broadcastModel(gameController.getModel());
|
||||
|
||||
serverTCP.notifyAll(gameController.getModel());
|
||||
|
||||
// Game execution
|
||||
while (true) {
|
||||
try {
|
||||
this.doFirstEven();
|
||||
this.doFirstEvent();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,14 @@ module it.polimi.ingsw.gc14 {
|
||||
|
||||
opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson;
|
||||
opens it.polimi.ingsw.gc14.Model to com.google.gson;
|
||||
opens it.polimi.ingsw.gc14.Model.GamePackage to com.google.gson;
|
||||
|
||||
exports it.polimi.ingsw.gc14;
|
||||
opens it.polimi.ingsw.gc14.Model.GamePackage to com.google.gson;
|
||||
|
||||
// RMI
|
||||
exports it.polimi.ingsw.gc14.Network.RMI.Common to java.rmi;
|
||||
exports it.polimi.ingsw.gc14.Network.RMI.Server to java.rmi;
|
||||
exports it.polimi.ingsw.gc14.Network.RMI.Client to java.rmi;
|
||||
exports it.polimi.ingsw.gc14.Network to java.rmi;
|
||||
exports it.polimi.ingsw.gc14.Model to java.rmi, com.google.gson;
|
||||
}
|
||||
Reference in New Issue
Block a user