feat: partially implemented LobbyManager and MessageRelay

This commit is contained in:
Yannik Bretschneider 2021-06-05 19:40:28 +02:00
parent 02b2a58cce
commit 2d27022655
3 changed files with 93 additions and 19 deletions

View File

@ -2,26 +2,36 @@ package uulm.teamname.marvelous.server.lobbymanager;
import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.events.Event;
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType; import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
import uulm.teamname.marvelous.gamelibrary.requests.Request;
import uulm.teamname.marvelous.server.lobby.Lobby; import uulm.teamname.marvelous.server.lobby.Lobby;
import java.util.Collections;
import java.util.HashSet; 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. * 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}. * The class is meant to be used in conjecture with {@link MessageRelay}.
*/ */
public class LobbyConnection { public class LobbyConnection implements Runnable {
private Lobby lobby; private final Lobby lobby;
public final String lobbyID;
private Participant player1, player2; private Participant player1, player2;
private final HashSet<Participant> spectators; private final HashSet<Participant> spectators;
private final BlockingQueue<Request[]> incomingRequests;
/** /**
* Creates a new LobbyConnection from a given lobby * Creates a new LobbyConnection from a given lobby
* @param lobby is the lobby that will be connected to * @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.lobby = lobby;
this.lobbyID = lobbyID;
this.spectators = new HashSet<>(10); this.spectators = new HashSet<>(10);
this.incomingRequests = new LinkedBlockingQueue<>();
} }
/** /**
@ -46,6 +56,10 @@ public class LobbyConnection {
return player2; return player2;
} }
public Set<Participant> getSpectators() {
return Collections.unmodifiableSet(spectators);
}
/** /**
* Adds a new player into the player1 slot * Adds a new player into the player1 slot
* @param player is the websocket to be added * @param player is the websocket to be added
@ -135,4 +149,14 @@ public class LobbyConnection {
public void terminateConnection() { public void terminateConnection() {
MessageRelay.getInstance().terminate(this); 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() {
}
} }

View File

@ -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<Participant, LobbyConnection> 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<Participant, LobbyConnection> getLobbies() {
return lobbies;
}
}

View File

@ -1,18 +1,28 @@
package uulm.teamname.marvelous.server.lobbymanager; package uulm.teamname.marvelous.server.lobbymanager;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.Tuple;
import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.events.Event;
import java.util.HashMap; 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 class MessageRelay {
public static MessageRelay instance; public static MessageRelay instance;
private final HashMap<WebSocket, LobbyConnection> lobbies;
private final BlockingQueue<Tuple<Participant, Event[]>> eventsToSend;
private MessageRelay() { private MessageRelay() {
this.lobbies = new HashMap<>(); this.eventsToSend = new LinkedBlockingQueue<>();
} }
public static MessageRelay getInstance() { public static MessageRelay getInstance() {
@ -22,23 +32,16 @@ public class MessageRelay {
return instance; return instance;
} }
public void relayMessage (WebSocket conn, String message) { public void relayMessage (WebSocket conn, LobbyConnection targetLobby) {
var targetLobby = lobbies.get(conn);
// TODO: Parse JSON // TODO: Parse JSON
// TODO: send to target lobby // TODO: send to target lobby
} }
public void sendMessage (LobbyConnection origin, Participant recipient, Event[] events) { public void sendMessage (LobbyConnection origin, Participant recipient, Event[] events) {
switch (recipient.type) { if (!origin.contains(recipient)) {
case PlayerOne -> { Logger.warn("Lobby sent message to not-in-lobby recipient '{}'", recipient.name);
} else {
} eventsToSend.add(Tuple.of(recipient, events));
case PlayerTwo -> {
}
case Spectator -> {
}
} }
} }
@ -48,8 +51,10 @@ public class MessageRelay {
* @param events are the {@link Event Events} to be broadcasted * @param events are the {@link Event Events} to be broadcasted
*/ */
public void broadcastEvents (LobbyConnection origin, Event[] events) { public void broadcastEvents (LobbyConnection origin, Event[] events) {
// TODO: Create JSON eventsToSend.add(Tuple.of(origin.getPlayer1(), events));
// TODO: send to target eventsToSend.add(Tuple.of(origin.getPlayer2(), events));
origin.getSpectators()
.forEach(spectator -> eventsToSend.add(Tuple.of(spectator, events)));
} }
/** /**