feat: improved UserManager

This commit is contained in:
Yannik Bretschneider 2021-06-07 01:45:51 +02:00
parent 0f559d09a5
commit 9e894a370e

View File

@ -1,5 +1,6 @@
package uulm.teamname.marvelous.server.netconnector;
import org.java_websocket.framing.CloseFrame;
import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.json.JSON;
import uulm.teamname.marvelous.gamelibrary.json.ValidationUtility;
@ -114,21 +115,23 @@ public class UserManager {
if (parsedMessage instanceof HelloServerMessage) {
Logger.trace("Message is instanceof HelloServerMessage, initiating handshake");
handshake(conn, (HelloServerMessage) parsedMessage);
} else if (parsedMessage instanceof ReconnectMessage) {
Logger.trace("Message is instanceof ReconnectMessage, initiating reconnect");
reconnectClient(conn, (ReconnectMessage) parsedMessage);
} else if (parsedMessage instanceof PlayerReadyMessage) {
Logger.trace("Message is instanceof PlayerReadyMessage, assigning lobby");
assignLobby(conn, (PlayerReadyMessage) parsedMessage);
playerReady(conn, (PlayerReadyMessage) parsedMessage);
} 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 {
} 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",
@ -182,7 +185,7 @@ public class UserManager {
var clientID = readyToReconnect.get(conn);
var participantToRestore = activeParticipants.get(clientID);
participantToRestore.setConnection(conn);
lobbyManager.restoreConnection(conn, participantToRestore);
synchronized (readyToReconnect) {
readyToReconnect.remove(conn);
@ -190,10 +193,10 @@ public class UserManager {
synchronized (inGame) {
inGame.put(conn, participantToRestore);
}
lobbyManager.restoreConnection(conn, participantToRestore);
// activeParticipants remains the same, as no players have been removed from the game
} else {
Logger.debug(
"Client {} refused reconnection, will therefore be put into readyToConnect clients",
Logger.debug("Client {} refused reconnection, will therefore be put into readyToConnect clients",
conn);
var clientID = readyToReconnect.get(conn);
@ -207,26 +210,40 @@ public class UserManager {
}
}
void assignLobby(WebSocket conn, PlayerReadyMessage message) {
if (readyToReconnect.containsKey(conn) || readyToConnect.containsKey(conn)) {
void playerReady(WebSocket conn, PlayerReadyMessage message) {
if (!message.startGame) {
removeUser(conn);
} else if (readyToReconnect.containsKey(conn) || readyToConnect.containsKey(conn)) {
Logger.trace("Connecting client to server");
SUID suid;
if (readyToConnect.containsKey(conn)) {
Logger.trace("Client in readyToConnect state, removing from list");
synchronized (readyToConnect) {
suid = readyToConnect.get(conn);
readyToConnect.remove(conn);
}
} else {
Logger.trace("Client in readyToReconnect state, removing from list");
synchronized (readyToReconnect) {
suid = readyToReconnect.get(conn);
readyToReconnect.remove(conn);
}
}
Participant participant;
Logger.trace("Letting LobbyManager assign lobby to client");
synchronized (inGame) {
var participant = lobbyManager.assignLobbyToConnection(conn, "SomeName", message);
participant = lobbyManager.assignLobbyToConnection(conn, suid.getName(), message);
inGame.put(conn, participant);
}
Logger.trace("Adding participants to activeParticipants for reconnection possibilities");
synchronized (activeParticipants) {
activeParticipants.put(suid, 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");
"WebSocket {} sent PlayerReadyMessage to server while not in connection ready state, " +
"sending error", conn);
sendError(conn, "Invalid message, as client is not in a connection-ready state");
}
}
@ -252,6 +269,33 @@ public class UserManager {
}
}
/**
* Method to call when removing a user from the game, e.g. on player timeout, or end of match
* @param conn is the connection to close
*/
public void removeUser(WebSocket conn) {
Logger.debug("Removing user from game");
if (conn == null) {
Logger.trace("Tried to remove user but connection was null, ignoring");
} else if (!isUserConnected(conn)) {
Logger.warn("Tried to remove non-connected user. This is probably a bug.");
} else {
if (inGame.containsKey(conn)) {
var participant = inGame.get(conn);
Logger.debug("Removing reconnect possibility for participant '{}'", participant.name);
var suid = new SUID(participant.name, participant.deviceID);
activeParticipants.remove(suid);
}
conn.close(CloseFrame.NORMAL);
// this automatically calls disconnectUser through the MarvelousServer
}
}
/**
* Method called exclusively from {@link MarvelousServer} on closed connection.
* @param conn
* @param closedByRemote
*/
void disconnectUser(WebSocket conn, boolean closedByRemote) {
// TODO: notify clients and such if the connection was in fact closed by the remote. Also remove participant
synchronized (newUsers) {