Skip to content

Commit

Permalink
Modify README.md, add player ping to server
Browse files Browse the repository at this point in the history
  • Loading branch information
Anto26 committed Jun 28, 2024
1 parent 0e467fb commit 42a52de
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 49 deletions.
29 changes: 10 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
# Project Creation
The project was created by running
```
mvn archetype:generate \
-DgroupId=it.polimi.ingsw \
-DartifactId=AM08 \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.4 \
-DinteractiveMode=false
```
# Progetto di Ingegneria del software, A.C. 2023/2024
Implementazione del gioco da tavolo `Codex naturalis` della Cranio Creations (C) scritta da:
- Francesco Caracciolo
- Antonino Ciancimino
- Gianluca Di Paola
- Davide Greco

Flags:
- `DgroupId`: unique base name of the company who created the project
- `DartifactId`: unique name of the project
- `DarchetypeArtifactId`: base struct of project


To ensure we all run the same maven version (so that if it compiles on one machine, it'll do so on all the others), we also
use `mvnw`, maven wrapper. This way, all the commands we have to run (`mvn build`, `mvn package`, `mvn test`...) will instead be run with `mvnw`
(`./mvnw build` ... on linux/macOS, `.\mvnw.cmd` on Windows)
Funzionalità avanzate implementate:
- Chat testuale
- Partite multiple
- Salvataggio periodico dei match e ripristino in caso di crash del server
Binary file modified deliveries/JAR/GUI.jar
Binary file not shown.
Binary file modified deliveries/JAR/Server.jar
Binary file not shown.
Binary file modified deliveries/JAR/TUI.jar
Binary file not shown.
13 changes: 12 additions & 1 deletion src/main/java/it/polimi/ingsw/client/network/NetworkHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import it.polimi.ingsw.utils.LeaderboardEntry;
import it.polimi.ingsw.utils.Pair;

import java.time.Duration;
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
Expand All @@ -25,6 +28,7 @@ public abstract class NetworkHandler implements RemoteViewInterface {
protected final String ipAddress;
protected final int port;
protected boolean connected = false;
protected Temporal lastPing;

/**
* Initialize the instance all its internal attributes.
Expand All @@ -50,8 +54,11 @@ public void startConnectionCheck() {
if (!connected) {
// If the connection lost is already acknowledged, shutdown the executor
executor.shutdown();

} else {
if (!ping()) {
Temporal now = Calendar.getInstance().getTime().toInstant();
ping();
if (Duration.between(lastPing, now).toMillis() > 10000) {
// If there is a connection error, notify the client and shutdown the executor
disconnect();
graphicalView.notifyConnectionLost();
Expand All @@ -62,6 +69,7 @@ public void startConnectionCheck() {

// Check every two second for connectivity
executor.scheduleAtFixedRate(pingServer, 0, 2, TimeUnit.SECONDS);
lastPing = Calendar.getInstance().getTime().toInstant();
}

/**
Expand Down Expand Up @@ -330,6 +338,9 @@ public void someoneDrewCard(String someoneUsername, DrawSource source, PlayableC
@Override
public void someoneJoined(String someoneUsername, List<String> joinedPlayers) {
graphicalView.someoneJoined(someoneUsername, joinedPlayers);
if (someoneUsername.equals(username)) {
this.startConnectionCheck();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.List;
import it.polimi.ingsw.client.frontend.GraphicalView;
import it.polimi.ingsw.controllers.PlayerController;
Expand Down Expand Up @@ -38,13 +40,12 @@ public class NetworkHandlerRMI extends NetworkHandler {
*/
public NetworkHandlerRMI(GraphicalView graphicalView, String ipAddress, int port) throws RemoteException {
super(graphicalView, ipAddress, port);

System.getProperties().setProperty("sun.rmi.transport.tcp.responseTimeout", "2000");
// Try to get a remote Server instance from the network
Registry registry = LocateRegistry.getRegistry(ipAddress, port);
try {
this.server = (ServerRMIInterface) registry.lookup("CodexNaturalisRMIServer");
connected = true;
this.startConnectionCheck();
} catch (NotBoundException e) {
// If the registry exists but the lookup string isn't found, exit the application since it's
// a programmatic error (it regards the code, not the app life cycle)
Expand Down Expand Up @@ -229,7 +230,9 @@ public void disconnect() {
@Override
public boolean ping() {
try {
return server.ping();
controller.ping();
super.lastPing = Calendar.getInstance().getTime().toInstant();
return true;
} catch (RemoteException e) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.io.IOException;
import java.net.Socket;
import java.rmi.RemoteException;
import java.util.Calendar;

import it.polimi.ingsw.client.frontend.GraphicalView;
import it.polimi.ingsw.controllers.PlayerControllerTCP;
import it.polimi.ingsw.gamemodel.DrawSource;
Expand Down Expand Up @@ -41,7 +43,6 @@ public NetworkHandlerTCP(GraphicalView graphicalView, String ipAddress, Integer
this.io = new IOHandler(socket);
new Thread(new ClientReceiver(this, socket)).start();
connected = true;
super.startConnectionCheck();
}

/**
Expand Down Expand Up @@ -202,6 +203,12 @@ public boolean ping() {
}
}

/**
* Confirm that the ping was successful
*/
public void pong() {
this.lastPing = Calendar.getInstance().getTime().toInstant();
}

/**
* Utility to send a message to the socket's output stream. If there was an error, it means the
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/it/polimi/ingsw/controllers/PlayerController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@
import it.polimi.ingsw.gamemodel.Player;
import it.polimi.ingsw.utils.GuiUtil;

import java.rmi.RemoteException;
import java.time.Duration;
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
* Controller for a match player, the only agent needing a view and so a controller in this
Expand All @@ -24,6 +32,7 @@
public abstract sealed class PlayerController implements MatchObserver permits PlayerControllerRMI, PlayerControllerTCP {
protected Player player;
protected final Match match;
private Temporal lastPing;

/**
* Instantiates the internal Player with the given username and sets the internal Match reference to
Expand All @@ -36,6 +45,20 @@ public abstract sealed class PlayerController implements MatchObserver permits P
public PlayerController(String username, Match match) {
this.player = new Player(username, match);
this.match = match;

// Check periodically if the connection with the remote view (NetworkHandler) is still alive
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

Runnable checkConnectivity = () -> {
Temporal now = Calendar.getInstance().getTime().toInstant();

if (lastPing != null && Duration.between(lastPing, now).toMillis() > 10000) {
match.removePlayer(player);
executor.shutdown();
}
};

executor.scheduleAtFixedRate(checkConnectivity, 0, 5, TimeUnit.SECONDS);
}

/**
Expand Down Expand Up @@ -97,4 +120,17 @@ public void sendJoined() throws IllegalArgumentException, AlreadyUsedUsernameExc
* Notifies the view that match has resumed after a server crash.
*/
public abstract void matchResumed();

/**
* Pings the remote controller in order to perceive if the connection is still alive and working.
* Always return true, since the false is implicit when returning a {@link RemoteException}
* when the connection is not working anymore.
*
* @return True if the connection is alive, false otherwise
*/
public boolean ping() {
lastPing = Calendar.getInstance().getTime().toInstant();

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,12 @@ public interface PlayerControllerRMIInterface extends Remote {
* @throws RemoteException If the remote object is considered not to be reachable any more and cannot return as usual
*/
void sendPrivateText(String recipient, String text) throws RemoteException;

/**
* Pings the server in order to perceive if the connection is still alive and working.
*
* @throws RemoteException If the connection to this class instance is not alive anymore
* @return True if the connection is alive, false otherwise
*/
boolean ping() throws RemoteException;
}
10 changes: 9 additions & 1 deletion src/main/java/it/polimi/ingsw/network/tcp/ClientListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,15 @@ private void createPlayerController(String username, Match match)
*/
private void executeRequest(String msg) {
try {

if (msg.equals("ping")) {
this.playerController.ping();
try {
io.writeMsg("pong");
} catch (IOException e ) {
// Not supposed to be handled
}
return;
}
ActionMessage message = (ActionMessage) parser.toMessage(msg);
if (msg != null) {
switch (message) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/it/polimi/ingsw/network/tcp/ClientReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ private void resumeMatch(MatchResumedMessage msg) throws IOException {
*/
private void parseMessage(String message) {
try {
if (message.equals("pong")) {
this.networkHandler.pong();
}
ResponseMessage response = (ResponseMessage) io.stringToMsg(message);
String username = response.getUsername();
switch (response) {
Expand Down Expand Up @@ -268,6 +271,7 @@ public void run() {
this.parseMessage(finalMessage);
}).start();
} catch (IOException | ClassNotFoundException e) {

}
}
}
Expand Down
17 changes: 1 addition & 16 deletions src/main/java/it/polimi/ingsw/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

/**
* The server class of this application. It's appointed with managing remote interactions with clients
Expand Down Expand Up @@ -137,18 +134,6 @@ public void createMatch(String matchName, int maxPlayers) throws ChosenMatchExce
}
}

/**
* Pings the server in order to perceive if the connection is still alive and working.
* Always return true, since the false is implicit in returning a {@link RemoteException}
* when the connection is not working anymore.
*
* @return True if the connection is alive, false otherwise
*/
@Override
public boolean ping() {
return true;
}

/**
* @return
*/
Expand Down
8 changes: 0 additions & 8 deletions src/main/java/it/polimi/ingsw/server/ServerRMIInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,4 @@ public interface ServerRMIInterface extends Remote {
* @throws WrongNameException If the chosen player username doesn't meet the alphanumerical criteria
*/
void createMatch(String matchName, int maxPlayers) throws RemoteException, ChosenMatchException, WrongNameException;

/**
* Pings the server in order to perceive if the connection is still alive and working.
*
* @throws RemoteException If the connection to this class instance is not alive anymore
* @return True if the connection is alive, false otherwise
*/
boolean ping() throws RemoteException;
}

0 comments on commit 42a52de

Please sign in to comment.