feat: implemented UserManager message forwarding
This commit is contained in:
parent
e689248f9e
commit
7af0fd40a1
@ -8,15 +8,18 @@ import uulm.teamname.marvelous.gamelibrary.messages.ErrorMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.client.*;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.server.HelloClientMessage;
|
||||
import uulm.teamname.marvelous.server.Server;
|
||||
import uulm.teamname.marvelous.server.lobbymanager.LobbyManager;
|
||||
import uulm.teamname.marvelous.server.lobbymanager.Participant;
|
||||
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** Class that manages users. It is meant as an extension to the {@link MarvelousServer} class, and should not be called
|
||||
* from anywhere else. This is the first place where messages are relayed to after they get received. This class is
|
||||
* responsible for handshakes, reconnects and WebSocket-to-Participant matching. <b>It is not thread-safe.</b>
|
||||
/** Class that manages users. It is meant as an extension to the {@link MarvelousServer} class. This is the first
|
||||
* place where messages are relayed to after they get received. This class is
|
||||
* responsible for handshakes, reconnects and WebSocket-to-Participant matching.
|
||||
* It is designed to be thread-safe. The Singleton of this class also contains a
|
||||
* {@link LobbyManager}, which manages the lobbys.
|
||||
*/
|
||||
public class UserManager {
|
||||
|
||||
@ -33,6 +36,10 @@ public class UserManager {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** The {@link LobbyManager} associated with the {@link UserManager}. It is therefore a kind of extension
|
||||
* to the current singleton, and may of course not be called from anywhere else */
|
||||
private final LobbyManager lobbyManager;
|
||||
|
||||
/** A set of users that aren't assigned to lobbies or character selection yet */
|
||||
private final HashSet<WebSocket> newUsers;
|
||||
|
||||
@ -64,12 +71,19 @@ public class UserManager {
|
||||
this.readyToReconnect = new HashMap<>();
|
||||
this.inGame = new HashMap<>();
|
||||
this.activeParticipants = new HashMap<>();
|
||||
|
||||
Logger.trace("Instantiating LobbyManager with message sending callbacks");
|
||||
this.lobbyManager = new LobbyManager(this::sendMessage, this::sendError);
|
||||
|
||||
Logger.trace("Instantiating JSON with the server's CharacterConfig");
|
||||
this.json = new JSON(Server.getCharacterConfig());
|
||||
}
|
||||
|
||||
/** Called on a new WebSocket connection. Places the WebSocket and its ResourceDescriptor in a HashMap. */
|
||||
void connectUser(WebSocket conn) {
|
||||
newUsers.add(conn);
|
||||
synchronized (newUsers) {
|
||||
newUsers.add(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +120,15 @@ public class UserManager {
|
||||
} else if (parsedMessage instanceof PlayerReadyMessage) {
|
||||
Logger.trace("Message is instanceof PlayerReadyMessage, assigning lobby");
|
||||
assignLobby(conn, (PlayerReadyMessage) parsedMessage);
|
||||
} else {
|
||||
} else if (parsedMessage instanceof CharacterSelectionMessage) {
|
||||
Logger.trace("Message is instanceof CharacterSelectionMessage, passing to LobbyConnection");
|
||||
charactersSelected(conn, (CharacterSelectionMessage) parsedMessage);
|
||||
} else if (parsedMessage instanceof RequestMessage) {
|
||||
Logger.trace("Message is instanceof RequestMessage, passing to LobbyConnection");
|
||||
relayRequestMessage(conn, (RequestMessage) parsedMessage);
|
||||
}
|
||||
|
||||
else {
|
||||
Logger.debug("Message '{}' has invalid type, Error will be sent");
|
||||
sendError(conn, String.format(
|
||||
"Message '%s' has invalid type, and cannot be processed on the server",
|
||||
@ -186,13 +208,48 @@ public class UserManager {
|
||||
}
|
||||
|
||||
void assignLobby(WebSocket conn, PlayerReadyMessage message) {
|
||||
// TODO: Assign a lobby
|
||||
if (readyToReconnect.containsKey(conn) || readyToConnect.containsKey(conn)) {
|
||||
if (readyToConnect.containsKey(conn)) {
|
||||
synchronized (readyToConnect) {
|
||||
readyToConnect.remove(conn);
|
||||
}
|
||||
} else {
|
||||
synchronized (readyToReconnect) {
|
||||
readyToReconnect.remove(conn);
|
||||
}
|
||||
}
|
||||
synchronized (inGame) {
|
||||
var participant = lobbyManager.assignLobbyToConnection(conn, "SomeName", message);
|
||||
inGame.put(conn, participant);
|
||||
}
|
||||
} else {
|
||||
Logger.debug(
|
||||
"WebSocket {} sent PlayerReadyMessage to server while not ready to connect, sending error",
|
||||
conn);
|
||||
sendError(conn, "Invalid message, as client is not ready to connect");
|
||||
}
|
||||
}
|
||||
|
||||
void charactersSelected(WebSocket conn, CharacterSelectionMessage message) {
|
||||
if (inGame.containsKey(conn)) {
|
||||
lobbyManager.relayMessageToLobby(inGame.get(conn), message);
|
||||
} else {
|
||||
Logger.debug(
|
||||
"WebSocket {} sent CharacterSelectionMessage to server while not ingame, sending error",
|
||||
conn);
|
||||
sendError(conn, "Invalid message, as client is not ingame");
|
||||
}
|
||||
}
|
||||
|
||||
void relayRequestMessage(Participant conn, RequestMessage message) {
|
||||
void relayRequestMessage(WebSocket conn, RequestMessage message) {
|
||||
if (inGame.containsKey(conn)) {
|
||||
lobbyManager.relayMessageToLobby(inGame.get(conn), message);
|
||||
} else {
|
||||
Logger.debug(
|
||||
"WebSocket {} sent RequestMessage to server while not ingame, sending error",
|
||||
conn);
|
||||
sendError(conn, "Invalid message, as client is not ingame");
|
||||
}
|
||||
}
|
||||
|
||||
void disconnectUser(WebSocket conn, boolean closedByRemote) {
|
||||
@ -200,22 +257,33 @@ public class UserManager {
|
||||
synchronized (newUsers) {
|
||||
newUsers.remove(conn);
|
||||
}
|
||||
synchronized (readyToConnect) {
|
||||
readyToConnect.remove(conn);
|
||||
}
|
||||
synchronized (readyToReconnect) {
|
||||
readyToReconnect.remove(conn);
|
||||
}
|
||||
synchronized (inGame) {
|
||||
inGame.remove(conn);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(WebSocket conn, BasicMessage message) {
|
||||
var jsonRepresentingMessage = json.stringify(message);
|
||||
if (jsonRepresentingMessage.isEmpty()) {
|
||||
Logger.warn("Message {} could not be serialized!", message);
|
||||
void sendMessage(WebSocket conn, BasicMessage message) {
|
||||
Logger.trace("Sending message to WebSocket {}", conn);
|
||||
if (conn == null) {
|
||||
Logger.debug("Message sent to non-existent websocket, ignoring");
|
||||
} else {
|
||||
conn.send(jsonRepresentingMessage.get());
|
||||
var jsonRepresentingMessage = json.stringify(message);
|
||||
if (jsonRepresentingMessage.isEmpty()) {
|
||||
Logger.warn("Message {} could not be serialized!", message);
|
||||
} else {
|
||||
conn.send(jsonRepresentingMessage.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Sends an {@link uulm.teamname.marvelous.gamelibrary.messages.ErrorMessage} to the specified user. */
|
||||
public void sendError(WebSocket conn, String error) {
|
||||
void sendError(WebSocket conn, String error) {
|
||||
Logger.debug("Sending error message '{}' to WebSocket {}", error, conn);
|
||||
var errorMessage = new ErrorMessage();
|
||||
errorMessage.message = error;
|
||||
@ -230,6 +298,7 @@ public class UserManager {
|
||||
}
|
||||
|
||||
public int getUserCount() {
|
||||
// FIXME: This is bugged at the moment
|
||||
return newUsers.size() + readyToConnect.size() + readyToReconnect.size() + inGame.size();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user