From 2d27022655648c48187e9b27de33df56b6870600 Mon Sep 17 00:00:00 2001 From: Yannik Bretschneider Date: Sat, 5 Jun 2021 19:40:28 +0200 Subject: [PATCH] feat: partially implemented LobbyManager and MessageRelay --- .../server/lobbymanager/LobbyConnection.java | 30 +++++++++++-- .../server/lobbymanager/LobbyManager.java | 45 +++++++++++++++++++ .../server/lobbymanager/MessageRelay.java | 37 ++++++++------- 3 files changed, 93 insertions(+), 19 deletions(-) create mode 100644 Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyManager.java diff --git a/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyConnection.java b/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyConnection.java index 34021de..6dc0c80 100644 --- a/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyConnection.java +++ b/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyConnection.java @@ -2,26 +2,36 @@ package uulm.teamname.marvelous.server.lobbymanager; import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType; +import uulm.teamname.marvelous.gamelibrary.requests.Request; import uulm.teamname.marvelous.server.lobby.Lobby; +import java.util.Collections; import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; /** * A class that handles the connection to the lobby. It contains distinct websockets for player1, player2 and spectators. * The class is meant to be used in conjecture with {@link MessageRelay}. */ -public class LobbyConnection { - private Lobby lobby; +public class LobbyConnection implements Runnable { + private final Lobby lobby; + public final String lobbyID; private Participant player1, player2; private final HashSet spectators; + private final BlockingQueue incomingRequests; /** * Creates a new LobbyConnection from a given lobby * @param lobby is the lobby that will be connected to + * @param lobbyID */ - public LobbyConnection(Lobby lobby) { + public LobbyConnection(Lobby lobby, String lobbyID) { this.lobby = lobby; + this.lobbyID = lobbyID; this.spectators = new HashSet<>(10); + this.incomingRequests = new LinkedBlockingQueue<>(); } /** @@ -46,6 +56,10 @@ public class LobbyConnection { return player2; } + public Set getSpectators() { + return Collections.unmodifiableSet(spectators); + } + /** * Adds a new player into the player1 slot * @param player is the websocket to be added @@ -135,4 +149,14 @@ public class LobbyConnection { public void terminateConnection() { MessageRelay.getInstance().terminate(this); } + + /** Send requests to the lobby that the LobbyConnection connects to */ + public void receiveRequests(Request... requests) { + this.incomingRequests.add(requests); + } + + @Override + public void run() { + + } } diff --git a/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyManager.java b/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyManager.java new file mode 100644 index 0000000..ae43009 --- /dev/null +++ b/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/LobbyManager.java @@ -0,0 +1,45 @@ +package uulm.teamname.marvelous.server.lobbymanager; + +import org.java_websocket.WebSocket; +import org.tinylog.Logger; +import uulm.teamname.marvelous.gamelibrary.messages.client.PlayerReadyMessage; +import uulm.teamname.marvelous.server.lobby.Lobby; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; + +public class LobbyManager { + private final HashMap lobbies; + + public LobbyManager() { + this.lobbies = new HashMap<>(); + } + + /** + * Assigns a lobby to the given participant. If there are no lobbies available, a new lobby will be created. + * The {@link WebSocket#getResourceDescriptor() ResourceDescriptor} is hereby preferred as the LobbyID, whereby + * spectators are always assigned to the lobby specified in said resourceDescriptor while players are connected + * to a lobby with a similar resourceDescriptor if the lobby they requested is already full + * @param playerName is the name of the player be assigned to a lobby + * @param message is the {@link PlayerReadyMessage} sent by the participant that triggered the LobbyAssignment + */ + public void assignLobbyToParticipant(WebSocket connection, String playerName, PlayerReadyMessage message) { + Logger.info("Assigning lobby to player '{}'", playerName); + + var resourceDescriptor = connection.getResourceDescriptor(); + if (resourceDescriptor.length() == 0) { + // TODO: generate new ResourceDescriptor + } + + + } + + /** A method to obtain the lobbies HashMap. Meant for testing, and shouldn't be used anywhere else. */ + @Deprecated + Map getLobbies() { + return lobbies; + } +} diff --git a/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/MessageRelay.java b/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/MessageRelay.java index e9e1703..f533872 100644 --- a/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/MessageRelay.java +++ b/Server/src/main/java/uulm/teamname/marvelous/server/lobbymanager/MessageRelay.java @@ -1,18 +1,28 @@ package uulm.teamname.marvelous.server.lobbymanager; import org.java_websocket.WebSocket; +import org.tinylog.Logger; +import uulm.teamname.marvelous.gamelibrary.Tuple; import uulm.teamname.marvelous.gamelibrary.events.Event; import java.util.HashMap; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +/** + * Relay for the messages field. It basically relays {@link Event} Events and + * {@link uulm.teamname.marvelous.gamelibrary.requests.Request} Requests to + * the participants or lobbies that they are supposed to be sent to. + */ public class MessageRelay { public static MessageRelay instance; - private final HashMap lobbies; + + private final BlockingQueue> eventsToSend; private MessageRelay() { - this.lobbies = new HashMap<>(); + this.eventsToSend = new LinkedBlockingQueue<>(); } public static MessageRelay getInstance() { @@ -22,23 +32,16 @@ public class MessageRelay { return instance; } - public void relayMessage (WebSocket conn, String message) { - var targetLobby = lobbies.get(conn); + public void relayMessage (WebSocket conn, LobbyConnection targetLobby) { // TODO: Parse JSON // TODO: send to target lobby } public void sendMessage (LobbyConnection origin, Participant recipient, Event[] events) { - switch (recipient.type) { - case PlayerOne -> { - - } - case PlayerTwo -> { - - } - case Spectator -> { - - } + if (!origin.contains(recipient)) { + Logger.warn("Lobby sent message to not-in-lobby recipient '{}'", recipient.name); + } else { + eventsToSend.add(Tuple.of(recipient, events)); } } @@ -48,8 +51,10 @@ public class MessageRelay { * @param events are the {@link Event Events} to be broadcasted */ public void broadcastEvents (LobbyConnection origin, Event[] events) { - // TODO: Create JSON - // TODO: send to target + eventsToSend.add(Tuple.of(origin.getPlayer1(), events)); + eventsToSend.add(Tuple.of(origin.getPlayer2(), events)); + origin.getSpectators() + .forEach(spectator -> eventsToSend.add(Tuple.of(spectator, events))); } /**