feat: partially implemented not yet refactored lobbyManager
This commit is contained in:
parent
e7a8f0e1e4
commit
7db692f790
@ -1,48 +1,196 @@
|
||||
package uulm.teamname.marvelous.server.lobbymanager;
|
||||
|
||||
import org.tinylog.Logger;
|
||||
import uulm.teamname.marvelous.gamelibrary.config.CharacterConfig;
|
||||
import uulm.teamname.marvelous.gamelibrary.config.PartyConfig;
|
||||
import uulm.teamname.marvelous.gamelibrary.config.ScenarioConfig;
|
||||
import uulm.teamname.marvelous.gamelibrary.Tuple;
|
||||
import uulm.teamname.marvelous.gamelibrary.config.CharacterProperties;
|
||||
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.BasicMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
|
||||
import uulm.teamname.marvelous.gamelibrary.requests.Request;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.client.CharacterSelectionMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.client.RequestMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.server.GameAssignmentMessage;
|
||||
import uulm.teamname.marvelous.server.Server;
|
||||
import uulm.teamname.marvelous.server.lobby.Lobby;
|
||||
import uulm.teamname.marvelous.server.netconnector.UserManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* 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 the participants inside of the lobby.
|
||||
* The class is meant to be used in conjecture with {@link MessageRelay}.
|
||||
*/
|
||||
public class LobbyConnection implements Runnable {
|
||||
private final Lobby lobby;
|
||||
private Lobby lobby;
|
||||
public final String gameID;
|
||||
private Participant player1, player2;
|
||||
private boolean characterSelection;
|
||||
|
||||
/** Whether the character selection phase is reached */
|
||||
private boolean inGame;
|
||||
private final HashSet<Participant> spectators;
|
||||
private final BlockingQueue<Request[]> incomingRequests;
|
||||
private final BlockingQueue<Tuple<Participant, BasicMessage>> incomingMessages;
|
||||
|
||||
/**
|
||||
* A callback executed to send a message, originating from the
|
||||
* {@link uulm.teamname.marvelous.server.netconnector.UserManager}
|
||||
*/
|
||||
private final BiConsumer<Participant, BasicMessage> sendMessageCallback;
|
||||
|
||||
// TODO: FIX THIS JAVADOC
|
||||
/**
|
||||
* Creates a new LobbyConnection, whereby a new {@link Lobby} is initialized.
|
||||
*/
|
||||
public LobbyConnection(String gameID,
|
||||
PartyConfig partyConfig,
|
||||
CharacterConfig characterConfig,
|
||||
ScenarioConfig scenarioConfig) {
|
||||
/** Creates a new LobbyConnection */
|
||||
public LobbyConnection(String gameID, BiConsumer<Participant, BasicMessage> sendMessageCallback) {
|
||||
this.gameID = gameID;
|
||||
this.sendMessageCallback = sendMessageCallback;
|
||||
this.spectators = new HashSet<>(10);
|
||||
this.incomingMessages = new LinkedBlockingQueue<>();
|
||||
this.characterSelection = false;
|
||||
this.inGame = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Logger.info("Starting Lobby thread for lobby '{}'", gameID);
|
||||
Logger.trace("Initializing lobby...");
|
||||
initializeLobby();
|
||||
|
||||
Logger.trace("Activating characterSelection state");
|
||||
this.characterSelection = true;
|
||||
|
||||
|
||||
Logger.info("Starting character selection process");
|
||||
Logger.trace("Finding twenty-four random characters");
|
||||
Tuple<CharacterProperties[], CharacterProperties[]> selectionPossibilities =
|
||||
Server.getCharacterConfig().getDisjointSetsOfPropertiesOfSize(12);
|
||||
|
||||
Logger.info("Sending GameAssignment message with random characters to players");
|
||||
var gameAssignmentMessage = new GameAssignmentMessage();
|
||||
gameAssignmentMessage.gameID = this.gameID;
|
||||
|
||||
// Send to player one with characters for player one
|
||||
gameAssignmentMessage.characterSelection = selectionPossibilities.item1;
|
||||
UserManager.getInstance().sendMessage(player1.getConnection(), gameAssignmentMessage);
|
||||
|
||||
// And send the others to player 2
|
||||
gameAssignmentMessage.characterSelection = selectionPossibilities.item2;
|
||||
UserManager.getInstance().sendMessage(player2.getConnection(), gameAssignmentMessage);
|
||||
|
||||
CharacterProperties[] playerOneSelection = null;
|
||||
CharacterProperties[] playerTwoSelection = null;
|
||||
|
||||
Logger.info("Entering GameAssignment state. Waiting for answer about selected characters from players.");
|
||||
while (characterSelection) {
|
||||
Tuple<Participant, BasicMessage> currentMessage = null;
|
||||
|
||||
try { // TODO: Exact duplication. Maybe extract?
|
||||
Logger.trace("Checking for messages. Currently the amount of messages is {}",
|
||||
incomingMessages.size());
|
||||
|
||||
if (incomingMessages.isEmpty()) {
|
||||
Logger.trace("LobbyConnection thread waiting for new messages...");
|
||||
Thread.currentThread().wait();
|
||||
Logger.trace("Lobby '{}' woken up", gameID);
|
||||
}
|
||||
|
||||
Logger.trace("Polling incoming message queue");
|
||||
currentMessage = incomingMessages.poll(100, TimeUnit.MILLISECONDS);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Logger.warn("LobbyConnection thread got interrupted. Exception: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (currentMessage == null) {
|
||||
continue;
|
||||
} else if (currentMessage.item2 instanceof CharacterSelectionMessage) {
|
||||
var origin = currentMessage.item1;
|
||||
var message = (CharacterSelectionMessage) currentMessage.item2;
|
||||
if (origin.type.equals(ParticipantType.Spectator)) {
|
||||
Logger.info("Spectator sent CharacterSelectionMessage. Sending error...");
|
||||
UserManager.getInstance().sendError(
|
||||
origin.getConnection(),
|
||||
"Spectators can't select characters");
|
||||
} else if (origin.type.equals(ParticipantType.PlayerOne)) {
|
||||
if (playerOneSelection == null) { // TODO: Extract this. This isn't beautiful at all.
|
||||
ArrayList<CharacterProperties> chosenCharacters = new ArrayList<>();
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (message.characters[i]) {
|
||||
chosenCharacters.add(selectionPossibilities.item1[i]);
|
||||
}
|
||||
}
|
||||
playerOneSelection = chosenCharacters.toArray(new CharacterProperties[0]);
|
||||
}
|
||||
Logger.info("Player 1 has selected their characters");
|
||||
} else {
|
||||
if (playerTwoSelection == null) {
|
||||
ArrayList<CharacterProperties> chosenCharacters = new ArrayList<>();
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (message.characters[i]) {
|
||||
chosenCharacters.add(selectionPossibilities.item2[i]);
|
||||
}
|
||||
}
|
||||
playerTwoSelection = chosenCharacters.toArray(new CharacterProperties[0]);
|
||||
}
|
||||
Logger.info("Player 2 has selected their characters");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while(inGame) {
|
||||
Tuple<Participant, BasicMessage> currentMessage = null;
|
||||
try {
|
||||
Logger.trace("Checking for messages. Currently the amount of messages is {}",
|
||||
incomingMessages.size());
|
||||
|
||||
if (incomingMessages.isEmpty()) {
|
||||
Logger.trace("LobbyConnection thread waiting for new messages...");
|
||||
Thread.currentThread().wait();
|
||||
Logger.trace("Lobby '{}' woken up", gameID);
|
||||
}
|
||||
|
||||
Logger.trace("Polling incoming message queue");
|
||||
currentMessage = incomingMessages.poll(100, TimeUnit.MILLISECONDS);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Logger.warn("LobbyConnection thread got interrupted. Exception: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (currentMessage == null) {
|
||||
Logger.trace("Message was null, continuing");
|
||||
continue;
|
||||
} else if (currentMessage.item2 instanceof CharacterSelectionMessage) {
|
||||
receiveCharacterSelection((CharacterSelectionMessage) currentMessage.item2);
|
||||
} else if (currentMessage.item2 instanceof RequestMessage) {
|
||||
receiveRequests((RequestMessage) currentMessage.item2);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Send messages to the lobbyConnection */
|
||||
public void receiveMessage(Participant participant, BasicMessage message) {
|
||||
this.incomingMessages.add(Tuple.of(participant, message));
|
||||
}
|
||||
|
||||
private void receiveRequests(RequestMessage message) {
|
||||
// TODO: implement this
|
||||
}
|
||||
|
||||
private void receiveCharacterSelection(CharacterSelectionMessage message) {
|
||||
// TODO: Implement proper character selection
|
||||
}
|
||||
|
||||
private void initializeLobby() {
|
||||
Logger.trace("Initializing lobby...");
|
||||
this.lobby = new Lobby(
|
||||
gameID,
|
||||
this,
|
||||
partyConfig,
|
||||
characterConfig,
|
||||
scenarioConfig);
|
||||
this.gameID = gameID;
|
||||
this.spectators = new HashSet<>(10);
|
||||
this.incomingRequests = new LinkedBlockingQueue<>();
|
||||
Server.getPartyConfig(),
|
||||
Server.getCharacterConfig(),
|
||||
Server.getScenarioConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,9 +200,7 @@ public class LobbyConnection implements Runnable {
|
||||
return player1 != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether there is a player2
|
||||
*/
|
||||
/** @return whether there is a player2 */
|
||||
public boolean hasPlayer2() {
|
||||
return player2 != null;
|
||||
}
|
||||
@ -176,16 +322,35 @@ public class LobbyConnection implements Runnable {
|
||||
|
||||
/** Kills all connections to client, as well as the lobby */
|
||||
public void terminateConnection() {
|
||||
MessageRelay.getInstance().terminate(this);
|
||||
// TODO: implement this
|
||||
}
|
||||
|
||||
/** Send requests to the lobby that the LobbyConnection connects to */
|
||||
public void receiveRequests(Request... requests) {
|
||||
this.incomingRequests.add(requests);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
LobbyConnection that = (LobbyConnection) o;
|
||||
return characterSelection == that.characterSelection && inGame == that.inGame && Objects.equals(lobby, that.lobby) && Objects.equals(gameID, that.gameID) && Objects.equals(player1, that.player1) && Objects.equals(player2, that.player2) && Objects.equals(spectators, that.spectators) && Objects.equals(incomingMessages, that.incomingMessages) && Objects.equals(sendMessageCallback, that.sendMessageCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public int hashCode() {
|
||||
return Objects.hash(lobby, gameID, player1, player2, characterSelection, inGame, spectators, incomingMessages, sendMessageCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LobbyConnection{" +
|
||||
"lobby=" + lobby +
|
||||
", gameID='" + gameID + '\'' +
|
||||
", player1=" + player1 +
|
||||
", player2=" + player2 +
|
||||
", characterSelection=" + characterSelection +
|
||||
", inGame=" + inGame +
|
||||
", spectators=" + spectators +
|
||||
", incomingMessages=" + incomingMessages +
|
||||
", sendMessageCallback=" + sendMessageCallback +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user