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.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<Participant> spectators;
private final BlockingQueue<Request[]> 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<Participant> 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() {
}
}

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;
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<WebSocket, LobbyConnection> lobbies;
private final BlockingQueue<Tuple<Participant, Event[]>> 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)));
}
/**