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.BasicMessage;
|
||||||
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
|
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
|
||||||
import uulm.teamname.marvelous.gamelibrary.messages.RoleEnum;
|
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.client.PlayerReadyMessage;
|
||||||
import uulm.teamname.marvelous.gamelibrary.messages.server.GameAssignmentMessage;
|
import uulm.teamname.marvelous.gamelibrary.messages.client.RequestMessage;
|
||||||
import uulm.teamname.marvelous.server.Server;
|
import uulm.teamname.marvelous.gamelibrary.messages.server.EventMessage;
|
||||||
import uulm.teamname.marvelous.server.lobby.Lobby;
|
import uulm.teamname.marvelous.server.lobby.Lobby;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -18,10 +19,15 @@ public class LobbyManager {
|
|||||||
private final HashMap<Participant, LobbyConnection> lobbies;
|
private final HashMap<Participant, LobbyConnection> lobbies;
|
||||||
private final HashMap<String, LobbyConnection> resourceDescriptorToLobby;
|
private final HashMap<String, LobbyConnection> resourceDescriptorToLobby;
|
||||||
private String localResourceDescriptor;
|
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.lobbies = new HashMap<>();
|
||||||
this.resourceDescriptorToLobby = 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
|
* 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 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
|
* @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);
|
Logger.info("Assigning lobby to player '{}'", playerName);
|
||||||
|
|
||||||
|
// If no resourceDescriptor is given, generate new one
|
||||||
var resourceDescriptor = connection.getResourceDescriptor();
|
var resourceDescriptor = connection.getResourceDescriptor();
|
||||||
if (resourceDescriptor == null || resourceDescriptor.length() == 0) {
|
if (resourceDescriptor == null || resourceDescriptor.length() == 0) {
|
||||||
Logger.trace("Resource descriptor is null, getting local one");
|
Logger.trace("Resource descriptor is null, getting local one");
|
||||||
@ -42,21 +50,30 @@ public class LobbyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LobbyConnection targetedLobby = resourceDescriptorToLobby.get(resourceDescriptor);
|
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);
|
||||||
|
} 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);
|
Logger.info("Lobby '{}' is non-existent, initializing lobby...", resourceDescriptor);
|
||||||
targetedLobby = initializeNewLobby(resourceDescriptor);
|
targetedLobby = initializeNewLobby(resourceDescriptor);
|
||||||
Logger.info("Adding mapping from resourceDescriptor {} to new lobby...", resourceDescriptor);
|
|
||||||
synchronized (resourceDescriptorToLobby) {
|
|
||||||
resourceDescriptorToLobby.put(resourceDescriptor, targetedLobby);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.trace("Obtaining lock on targetedLobby '{}'", targetedLobby.gameID);
|
Logger.trace("Obtaining lock on targetedLobby '{}'", targetedLobby.gameID);
|
||||||
synchronized (targetedLobby) {
|
synchronized (targetedLobby) {
|
||||||
|
|
||||||
Participant participant;
|
|
||||||
|
|
||||||
Logger.debug("Assigning participant to lobby");
|
Logger.debug("Assigning participant to lobby");
|
||||||
if (message.role.equals(RoleEnum.SPECTATOR)) {
|
if (message.role.equals(RoleEnum.SPECTATOR)) {
|
||||||
Logger.trace("Generating new participant with type 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);
|
participant.name, targetedLobby.gameID);
|
||||||
synchronized (lobbies) {
|
synchronized (lobbies) {
|
||||||
lobbies.put(participant, targetedLobby);
|
lobbies.put(participant, targetedLobby);
|
||||||
}
|
}
|
||||||
Logger.trace("Relaying message to newly created Lobby");
|
if (targetedLobby.isFull() && !LobbyRunner.getInstance().isStarted(targetedLobby)) {
|
||||||
targetedLobby.receiveMessage(participant, message);
|
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) {
|
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);
|
var lobby = resourceDescriptorToLobby.get(localResourceDescriptor);
|
||||||
if (lobby != null) {
|
if (lobby != null) {
|
||||||
if (!lobby.hasFreePlayerSpot()) {
|
if (lobby.isFull()) {
|
||||||
Logger.debug("Lobby is full, generating new local resourceDescriptor");
|
Logger.debug("Lobby is full, generating new local resourceDescriptor");
|
||||||
while (resourceDescriptorToLobby.get(localResourceDescriptor) != null) {
|
while (resourceDescriptorToLobby.get(localResourceDescriptor) != null) {
|
||||||
localResourceDescriptor = RandomWordGenerator.generateTwoWords();
|
localResourceDescriptor = RandomWordGenerator.generateTwoWords();
|
||||||
|
Loading…
Reference in New Issue
Block a user