feat: implemented callback-based message sending
This commit is contained in:
parent
2acf340482
commit
6043a21e22
@ -5,9 +5,10 @@ import org.tinylog.Logger;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.BasicMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.RoleEnum;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.client.CharacterSelectionMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.client.PlayerReadyMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.server.GameAssignmentMessage;
|
||||
import uulm.teamname.marvelous.server.Server;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.client.RequestMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.server.EventMessage;
|
||||
import uulm.teamname.marvelous.server.lobby.Lobby;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -18,10 +19,15 @@ public class LobbyManager {
|
||||
private final HashMap<Participant, LobbyConnection> lobbies;
|
||||
private final HashMap<String, LobbyConnection> resourceDescriptorToLobby;
|
||||
private String localResourceDescriptor;
|
||||
private final BiConsumer<WebSocket, BasicMessage> sendMessageCallback;
|
||||
private final BiConsumer<WebSocket, String> sendErrorCallback;
|
||||
|
||||
public LobbyManager() {
|
||||
public LobbyManager(BiConsumer<WebSocket, BasicMessage> sendMessageCallback,
|
||||
BiConsumer<WebSocket, String> sendErrorCallback) {
|
||||
this.lobbies = new HashMap<>();
|
||||
this.resourceDescriptorToLobby = new HashMap<>();
|
||||
this.sendMessageCallback = sendMessageCallback;
|
||||
this.sendErrorCallback = sendErrorCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,10 +37,12 @@ public class LobbyManager {
|
||||
* 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
|
||||
* @return the {@link Participant} that was actually assigned to the lobby
|
||||
*/
|
||||
public void assignLobbyToParticipant(WebSocket connection, String playerName, PlayerReadyMessage message) {
|
||||
public Participant assignLobbyToConnection(WebSocket connection, String playerName, PlayerReadyMessage message) {
|
||||
Logger.info("Assigning lobby to player '{}'", playerName);
|
||||
|
||||
// If no resourceDescriptor is given, generate new one
|
||||
var resourceDescriptor = connection.getResourceDescriptor();
|
||||
if (resourceDescriptor == null || resourceDescriptor.length() == 0) {
|
||||
Logger.trace("Resource descriptor is null, getting local one");
|
||||
@ -42,21 +50,30 @@ public class LobbyManager {
|
||||
}
|
||||
|
||||
LobbyConnection targetedLobby = resourceDescriptorToLobby.get(resourceDescriptor);
|
||||
Participant participant;
|
||||
|
||||
if (targetedLobby == null || !targetedLobby.hasFreePlayerSpot()) {
|
||||
// If lobby is filled, generate a new ResourceDescriptor
|
||||
|
||||
if (targetedLobby == null) {
|
||||
if (LobbyRunner.getInstance().canAddLobby()) {
|
||||
Logger.info("Lobby '{}' is non-existent, initializing lobby...", resourceDescriptor);
|
||||
targetedLobby = initializeNewLobby(resourceDescriptor);
|
||||
Logger.info("Adding mapping from resourceDescriptor {} to new lobby...", resourceDescriptor);
|
||||
synchronized (resourceDescriptorToLobby) {
|
||||
resourceDescriptorToLobby.put(resourceDescriptor, targetedLobby);
|
||||
} else {
|
||||
Logger.info("No free lobby spot available, sending error and disconnecting Client");
|
||||
|
||||
}
|
||||
|
||||
} else if (targetedLobby.isFull() && !message.role.equals(RoleEnum.SPECTATOR)) {
|
||||
Logger.info("Lobby '{}' is already full, assigning player '{}' to new lobby",
|
||||
resourceDescriptor,
|
||||
playerName);
|
||||
resourceDescriptor = getLocalResourceDescriptor();
|
||||
Logger.info("Lobby '{}' is non-existent, initializing lobby...", resourceDescriptor);
|
||||
targetedLobby = initializeNewLobby(resourceDescriptor);
|
||||
}
|
||||
|
||||
Logger.trace("Obtaining lock on targetedLobby '{}'", targetedLobby.gameID);
|
||||
synchronized (targetedLobby) {
|
||||
|
||||
Participant participant;
|
||||
|
||||
Logger.debug("Assigning participant to lobby");
|
||||
if (message.role.equals(RoleEnum.SPECTATOR)) {
|
||||
Logger.trace("Generating new participant with type spectator");
|
||||
@ -78,19 +95,60 @@ public class LobbyManager {
|
||||
|
||||
}
|
||||
}
|
||||
Logger.trace("Adding mapping from participant '{}' to lobby {}",
|
||||
Logger.trace("Adding mapping from participant '{}' to lobby '{}'",
|
||||
participant.name, targetedLobby.gameID);
|
||||
synchronized (lobbies) {
|
||||
lobbies.put(participant, targetedLobby);
|
||||
}
|
||||
Logger.trace("Relaying message to newly created Lobby");
|
||||
targetedLobby.receiveMessage(participant, message);
|
||||
if (targetedLobby.isFull() && !LobbyRunner.getInstance().isStarted(targetedLobby)) {
|
||||
Logger.info("Lobby '{}' was full, starting...", targetedLobby.gameID);
|
||||
LobbyRunner.getInstance().startLobby(targetedLobby);
|
||||
}
|
||||
}
|
||||
return participant;
|
||||
}
|
||||
|
||||
public void relayMessageToLobby(Participant origin, CharacterSelectionMessage message) {
|
||||
var targetedLobby = lobbies.get(origin);
|
||||
if (targetedLobby == null) {
|
||||
Logger.warn("Tried to send character selection message to non-existent lobby. This is probably a bug.");
|
||||
} else if (!targetedLobby.isActive()) {
|
||||
Logger.info("Tried sending message to inactive lobby, sending error...");
|
||||
sendErrorCallback.accept(origin.getConnection(), "message could not be processed as " +
|
||||
"lobby has not yet started as you are the only player in the lobby at the moment");
|
||||
} else {
|
||||
targetedLobby.receiveMessage(origin, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void relayMessageToLobby(Participant origin, RequestMessage message) {
|
||||
var targetedLobby = lobbies.get(origin);
|
||||
if (targetedLobby == null) {
|
||||
Logger.warn("Tried to send event message to non-existent lobby. This is probably a bug.");
|
||||
} else if (!targetedLobby.isActive()) {
|
||||
Logger.info("Tried sending message to inactive lobby, sending error...");
|
||||
sendErrorCallback.accept(origin.getConnection(), "message could not be processed as " +
|
||||
"lobby has not yet started as you are the only player in the lobby at the moment");
|
||||
} else {
|
||||
targetedLobby.receiveMessage(origin, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new {@link LobbyConnection} with a not yet initialized {@link Lobby}. The {@link LobbyConnection}
|
||||
* gets some GameID, and also the sendMessageCallback and sendErrorCallback from the
|
||||
* {@link uulm.teamname.marvelous.server.netconnector.UserManager}.
|
||||
* @param gameID is the ID that the {@link LobbyConnection} is initialized with. This is normally
|
||||
* the resourceDescriptor.
|
||||
* @return the newly initialized LobbyConnection
|
||||
*/
|
||||
private LobbyConnection initializeNewLobby(String gameID) {
|
||||
return new LobbyConnection(gameID);
|
||||
var lobby = new LobbyConnection(gameID, sendMessageCallback, sendErrorCallback);
|
||||
Logger.debug("Adding mapping from gameID (resourceDescriptor) '{}' to new lobby...", gameID);
|
||||
synchronized (resourceDescriptorToLobby) {
|
||||
resourceDescriptorToLobby.put(gameID, lobby);
|
||||
}
|
||||
return lobby;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +164,7 @@ public class LobbyManager {
|
||||
}
|
||||
var lobby = resourceDescriptorToLobby.get(localResourceDescriptor);
|
||||
if (lobby != null) {
|
||||
if (!lobby.hasFreePlayerSpot()) {
|
||||
if (lobby.isFull()) {
|
||||
Logger.debug("Lobby is full, generating new local resourceDescriptor");
|
||||
while (resourceDescriptorToLobby.get(localResourceDescriptor) != null) {
|
||||
localResourceDescriptor = RandomWordGenerator.generateTwoWords();
|
||||
|
Loading…
Reference in New Issue
Block a user