feat: implemented Character selection and relaying to lobby
This commit is contained in:
parent
7af0fd40a1
commit
21bfac7d75
@ -1,5 +1,6 @@
|
||||
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.config.CharacterProperties;
|
||||
@ -8,10 +9,9 @@ import uulm.teamname.marvelous.gamelibrary.messages.BasicMessage;
|
||||
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
|
||||
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.gamelibrary.messages.server.*;
|
||||
import uulm.teamname.marvelous.server.Server;
|
||||
import uulm.teamname.marvelous.server.lobby.Lobby;
|
||||
import uulm.teamname.marvelous.server.netconnector.UserManager;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
@ -20,44 +20,65 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
* A class that handles the connection to the lobby. It contains the participants inside of the lobby. The class
|
||||
* implements runnable and harbors a thread, but should exclusively be run from the {@link LobbyRunner} class.
|
||||
*/
|
||||
public class LobbyConnection implements Runnable {
|
||||
private Lobby lobby;
|
||||
public final String gameID;
|
||||
private Participant player1, player2;
|
||||
private boolean characterSelection;
|
||||
|
||||
/** Whether the character selection phase is reached */
|
||||
/** Whether the character selection phase is active. True while active, false after done */
|
||||
private boolean characterSelectionActive;
|
||||
|
||||
/** Whether the ingame phase is reached */
|
||||
private boolean inGame;
|
||||
|
||||
/** A boolean set true if the thread should be closed. Basically a terminator. */
|
||||
private boolean active;
|
||||
|
||||
private final HashSet<Participant> spectators;
|
||||
private final BlockingQueue<Tuple<Participant, BasicMessage>> incomingMessages;
|
||||
|
||||
private final BiConsumer<WebSocket, BasicMessage> sendMessageCallback;
|
||||
private final BiConsumer<WebSocket, String> sendErrorCallback;
|
||||
|
||||
// TODO: FIX THIS JAVADOC
|
||||
|
||||
/** Creates a new LobbyConnection */
|
||||
public LobbyConnection(String gameID) {
|
||||
public LobbyConnection(String gameID,
|
||||
BiConsumer<WebSocket, BasicMessage> sendMessageCallback,
|
||||
BiConsumer<WebSocket, String> sendErrorCallback) {
|
||||
this.gameID = gameID;
|
||||
this.sendMessageCallback = sendMessageCallback;
|
||||
this.sendErrorCallback = sendErrorCallback;
|
||||
this.spectators = new HashSet<>(10);
|
||||
this.incomingMessages = new LinkedBlockingQueue<>();
|
||||
this.characterSelection = false;
|
||||
this.characterSelectionActive = false;
|
||||
this.inGame = false;
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
// Variables for Character Selection
|
||||
Tuple<CharacterProperties[], CharacterProperties[]> selectionPossibilities;
|
||||
|
||||
CharacterProperties[] playerOneSelection = null;
|
||||
CharacterProperties[] playerTwoSelection = null;
|
||||
|
||||
@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.debug("Activating lobbyConnection");
|
||||
this.active = true;
|
||||
|
||||
Logger.debug("Activating characterSelection state");
|
||||
this.characterSelectionActive = true;
|
||||
|
||||
|
||||
Logger.info("Starting character selection process");
|
||||
Logger.trace("Finding twenty-four random characters");
|
||||
Tuple<CharacterProperties[], CharacterProperties[]> selectionPossibilities =
|
||||
Server.getCharacterConfig().getDisjointSetsOfPropertiesOfSize(12);
|
||||
selectionPossibilities = Server.getCharacterConfig().getDisjointSetsOfPropertiesOfSize(12);
|
||||
|
||||
Logger.info("Sending GameAssignment message with random characters to players");
|
||||
var gameAssignmentMessage = new GameAssignmentMessage();
|
||||
@ -65,115 +86,226 @@ public class LobbyConnection implements Runnable {
|
||||
|
||||
// Send to player one with characters for player one
|
||||
gameAssignmentMessage.characterSelection = selectionPossibilities.item1;
|
||||
UserManager.getInstance().sendMessage(player1.getConnection(), gameAssignmentMessage);
|
||||
sendMessage(player1, gameAssignmentMessage);
|
||||
|
||||
// And send the others to player 2
|
||||
gameAssignmentMessage.characterSelection = selectionPossibilities.item2;
|
||||
UserManager.getInstance().sendMessage(player2.getConnection(), gameAssignmentMessage);
|
||||
sendMessage(player2, gameAssignmentMessage);
|
||||
|
||||
CharacterProperties[] playerOneSelection = null;
|
||||
CharacterProperties[] playerTwoSelection = null;
|
||||
// Also, send the GeneralAssignment message to all spectators
|
||||
var generalAssignmentMessage = new GeneralAssignmentMessage();
|
||||
generalAssignmentMessage.gameID = gameID;
|
||||
broadcastToSpectators(generalAssignmentMessage);
|
||||
|
||||
Logger.info("Entering GameAssignment state. Waiting for answer about selected characters from players.");
|
||||
while (characterSelection) {
|
||||
Tuple<Participant, BasicMessage> currentMessage = null;
|
||||
while (characterSelectionActive && active) {
|
||||
var currentMessage = getMessageAsync(1000);
|
||||
|
||||
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) {
|
||||
if (!active) {
|
||||
Logger.info("Lobby '{}' is terminating. Exiting...", gameID);
|
||||
return;
|
||||
} else if (currentMessage == null) {
|
||||
Logger.trace("Message was null, continuing"); // TODO: remove for production
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
Logger.debug("CharacterSelectionMessage sent by Player '{}' during character selection phase",
|
||||
origin.name);
|
||||
characterSelectionActive = receiveCharacterSelection(origin, message);
|
||||
|
||||
Logger.trace("Sending confirmSelectionMessage to player1");
|
||||
var replyMessage = new ConfirmSelectionMessage();
|
||||
replyMessage.selectionComplete = !characterSelectionActive;
|
||||
sendMessage(origin, replyMessage);
|
||||
} else if (currentMessage.item2 instanceof RequestMessage) {
|
||||
var origin = currentMessage.item1;
|
||||
// var message = (RequestMessage) currentMessage.item2; this is ignored here
|
||||
|
||||
Logger.debug("RequestMessage sent by Player '{}' during character selection phase",
|
||||
origin.name);
|
||||
sendError(
|
||||
currentMessage.item1,
|
||||
"Requests rejected as ingame phase not reached yet");
|
||||
} else {
|
||||
Logger.warn("Message that isn't of type RequestMessage or CharacacterSelectionMessage" +
|
||||
"received in Lobby. This is probably a bug.");
|
||||
sendError(
|
||||
currentMessage.item1,
|
||||
"Message couldn't be processed by the lobby, as its type was invalid");
|
||||
}
|
||||
}
|
||||
|
||||
while(inGame) {
|
||||
Tuple<Participant, BasicMessage> currentMessage = null;
|
||||
try {
|
||||
Logger.trace("Checking for messages. Currently the amount of messages is {}",
|
||||
incomingMessages.size());
|
||||
Logger.trace("End of character selection phase reached. Lobby termination is '{}'", active);
|
||||
if (!active) {
|
||||
Logger.info("Lobby '{}' is terminating. Exiting... ", gameID);
|
||||
return;
|
||||
} else {
|
||||
|
||||
if (incomingMessages.isEmpty()) {
|
||||
Logger.trace("LobbyConnection thread waiting for new messages...");
|
||||
Thread.currentThread().wait();
|
||||
Logger.trace("Lobby '{}' woken up", gameID);
|
||||
}
|
||||
Logger.info("Sending GameStructure message to clients as the game is starting");
|
||||
// Building GameStructure message
|
||||
var gameStructureMessage = new GameStructureMessage();
|
||||
gameStructureMessage.playerOneName = player1.name;
|
||||
gameStructureMessage.playerTwoName = player2.name;
|
||||
gameStructureMessage.playerOneCharacters = playerOneSelection;
|
||||
gameStructureMessage.playerTwoCharacters = playerTwoSelection;
|
||||
gameStructureMessage.matchconfig = Server.getPartyConfig();
|
||||
gameStructureMessage.scenarioconfig = Server.getScenarioConfig();
|
||||
|
||||
Logger.trace("Polling incoming message queue");
|
||||
currentMessage = incomingMessages.poll(100, TimeUnit.MILLISECONDS);
|
||||
// Sending GameStructure message with fitting assignment
|
||||
gameStructureMessage.assignment = ParticipantType.PlayerOne;
|
||||
sendMessage(player1, gameStructureMessage);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Logger.warn("LobbyConnection thread got interrupted. Exception: " + e.getMessage());
|
||||
}
|
||||
gameStructureMessage.assignment = ParticipantType.PlayerTwo;
|
||||
sendMessage(player2, gameStructureMessage);
|
||||
|
||||
if (currentMessage == null) {
|
||||
Logger.trace("Message was null, continuing");
|
||||
gameStructureMessage.assignment = ParticipantType.Spectator;
|
||||
broadcastToSpectators(gameStructureMessage);
|
||||
}
|
||||
|
||||
|
||||
Logger.info("Entering Ingame phase");
|
||||
inGame = true;
|
||||
Logger.trace("Initializing lobby...");
|
||||
initializeLobby();
|
||||
while (inGame && active) {
|
||||
Tuple<Participant, BasicMessage> currentMessage = getMessageAsync(1000);
|
||||
|
||||
if (!active) {
|
||||
Logger.info("Lobby '{}' is terminating. Exiting...", gameID);
|
||||
return;
|
||||
} else if (currentMessage == null) {
|
||||
Logger.trace("Message was null, continuing"); // TODO: remove for production
|
||||
continue;
|
||||
} else if (currentMessage.item2 instanceof CharacterSelectionMessage) {
|
||||
receiveCharacterSelection((CharacterSelectionMessage) currentMessage.item2);
|
||||
var origin = currentMessage.item1;
|
||||
var message = (CharacterSelectionMessage) currentMessage.item2;
|
||||
Logger.debug("CharacterSelectionMessage sent by Player '{}' during ingame phase", origin.name);
|
||||
receiveCharacterSelection(origin, message);
|
||||
} else if (currentMessage.item2 instanceof RequestMessage) {
|
||||
receiveRequests((RequestMessage) currentMessage.item2);
|
||||
var origin = currentMessage.item1;
|
||||
var message = (RequestMessage) currentMessage.item2;
|
||||
Logger.debug("RequestMessage sent by Player '{}' during ingame phase",
|
||||
origin.name);
|
||||
receiveRequests(origin, message);
|
||||
} else {
|
||||
Logger.warn("Message that isn't of type RequestMessage or CharacacterSelectionMessage" +
|
||||
"received in Lobby. This is probably a bug.");
|
||||
sendError(
|
||||
currentMessage.item1,
|
||||
"Message couldn't be processed by the lobby, as its type was invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Send messages to the lobbyConnection */
|
||||
public void receiveMessage(Participant participant, BasicMessage message) {
|
||||
this.incomingMessages.add(Tuple.of(participant, message));
|
||||
/**
|
||||
* Tries to read the next message in the messageQueue. waits for timeoutMillis
|
||||
* for a queue item
|
||||
*
|
||||
* @param timeoutMillis is the amount of time the method waits until continuing even though not being notified.
|
||||
*/
|
||||
private Tuple<Participant, BasicMessage> getMessageAsync(int timeoutMillis) {
|
||||
Tuple<Participant, BasicMessage> currentMessage = null;
|
||||
try {
|
||||
Logger.trace("Checking for messages. Currently the amount of messages is {}",
|
||||
incomingMessages.size());
|
||||
|
||||
Logger.trace("Polling incoming message queue");
|
||||
currentMessage = incomingMessages.poll(timeoutMillis, TimeUnit.MILLISECONDS);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Logger.warn("LobbyConnection thread got interrupted. Exception: " + e.getMessage());
|
||||
}
|
||||
return currentMessage;
|
||||
}
|
||||
|
||||
private void receiveRequests(RequestMessage message) {
|
||||
// TODO: implement this
|
||||
/** Send messages to the lobbyConnection. This is thread-safe, and meant to be called from the outside. */
|
||||
public void receiveMessage(Participant origin, BasicMessage message) {
|
||||
Logger.trace("Lobby '{}' received message from participant '{}'", gameID, origin.name);
|
||||
this.incomingMessages.add(Tuple.of(origin, message));
|
||||
}
|
||||
|
||||
private void receiveCharacterSelection(CharacterSelectionMessage message) {
|
||||
// TODO: Implement proper character selection
|
||||
private void receiveRequests(Participant origin, RequestMessage message) {
|
||||
System.out.println("REMOVE THIS PRINTLN: received request message " + message.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method executed on Character selection. Hereby the local fields {@link LobbyConnection#selectionPossibilities},
|
||||
* {@link LobbyConnection#playerOneSelection} and {@link LobbyConnection#playerTwoSelection} are checked and
|
||||
* populated
|
||||
*
|
||||
* @param origin is the participant that sent the message
|
||||
* @param message is the message triggering the CharacterSelection method
|
||||
* @return true if CharacterSelection is now completed, and false otherwise. If the method is called outside of the
|
||||
* CharacterSelection phase, true is returned, as the characterSelection is after all done
|
||||
*/
|
||||
private boolean receiveCharacterSelection(Participant origin, CharacterSelectionMessage message) {
|
||||
if (this.characterSelectionActive) {
|
||||
if (!hasRightNumberOfTrues(message.characters, 6)) {
|
||||
Logger.debug("Player chose non-six number of characters, which is invalid. Sending error");
|
||||
sendError(origin, "Cannot select characters as character choices wasn't 6");
|
||||
} else {
|
||||
switch (origin.type) {
|
||||
case PlayerOne -> {
|
||||
if (playerOneSelection == null) {
|
||||
playerOneSelection = getChosenCharacters(
|
||||
selectionPossibilities.item1,
|
||||
message.characters);
|
||||
Logger.info("Player 1 has selected their characters");
|
||||
} else {
|
||||
Logger.debug("Player 1 tried to select characters twice, sending error");
|
||||
sendError(origin,
|
||||
"Cannot select characters as characters were already selected"
|
||||
);
|
||||
}
|
||||
}
|
||||
case PlayerTwo -> {
|
||||
if (playerTwoSelection == null) {
|
||||
Logger.trace("Checking whether there are actually 6 choices");
|
||||
playerTwoSelection = getChosenCharacters(
|
||||
selectionPossibilities.item1,
|
||||
message.characters);
|
||||
Logger.info("Player 1 has selected their characters");
|
||||
} else {
|
||||
Logger.debug("Player 1 tried to select characters twice, sending error");
|
||||
sendError(origin,
|
||||
"Cannot select characters as characters were already selected");
|
||||
}
|
||||
}
|
||||
case Spectator -> {
|
||||
Logger.info("Spectator sent CharacterSelectionMessage. Sending error...");
|
||||
sendError(origin, "Spectators can't select characters");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Logger.debug("Participant '{}' sent a CharacterSelectionMessage outside of " +
|
||||
"the CharacterSelectionPhase, sending error", origin.name);
|
||||
sendError(origin, "The character selection phase is already over");
|
||||
}
|
||||
return !characterSelectionActive || (playerOneSelection != null && playerTwoSelection != null);
|
||||
}
|
||||
|
||||
private CharacterProperties[] getChosenCharacters(CharacterProperties[] possibleChoices, Boolean[] choices) {
|
||||
ArrayList<CharacterProperties> chosenCharacters = new ArrayList<>();
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (choices[i]) {
|
||||
chosenCharacters.add(possibleChoices[i]);
|
||||
}
|
||||
}
|
||||
return chosenCharacters.toArray(new CharacterProperties[0]);
|
||||
}
|
||||
|
||||
private boolean hasRightNumberOfTrues(Boolean[] values, int expected) {
|
||||
int choices = Arrays.stream(values)
|
||||
.mapToInt(choice -> choice ? 1 : 0)
|
||||
.sum();
|
||||
if (choices == expected) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeLobby() {
|
||||
@ -199,8 +331,8 @@ public class LobbyConnection implements Runnable {
|
||||
}
|
||||
|
||||
/** @return whether a player can join the lobby */
|
||||
public boolean hasFreePlayerSpot() {
|
||||
return !(hasPlayer1() && hasPlayer2());
|
||||
public boolean isFull() {
|
||||
return hasPlayer1() && hasPlayer2();
|
||||
}
|
||||
|
||||
public Participant getPlayer1() {
|
||||
@ -217,6 +349,7 @@ public class LobbyConnection implements Runnable {
|
||||
|
||||
/**
|
||||
* Adds a new player into the player1 slot
|
||||
*
|
||||
* @param player is the websocket to be added
|
||||
* @return true if added successfully, and false otherwise
|
||||
*/
|
||||
@ -232,6 +365,7 @@ public class LobbyConnection implements Runnable {
|
||||
|
||||
/**
|
||||
* Adds a new player into the player1 slot
|
||||
*
|
||||
* @param player is the websocket to be added
|
||||
* @return true if added successfully, and false otherwise
|
||||
*/
|
||||
@ -247,6 +381,7 @@ public class LobbyConnection implements Runnable {
|
||||
|
||||
/**
|
||||
* Adds a new player into either the player1, or if full, player2 slot
|
||||
*
|
||||
* @param player is the websocket to be added
|
||||
* @return true if added successfully, and false otherwise
|
||||
*/
|
||||
@ -287,35 +422,65 @@ public class LobbyConnection implements Runnable {
|
||||
return player1 == participant || player2 == participant || spectators.contains(participant);
|
||||
}
|
||||
|
||||
// Methods to send messages
|
||||
|
||||
private void sendMessage(Participant recipient, BasicMessage message) {
|
||||
sendMessageCallback.accept(recipient.getConnection(), message);
|
||||
}
|
||||
|
||||
private void broadcast(BasicMessage message) {
|
||||
sendMessage(player1, message);
|
||||
sendMessage(player2, message);
|
||||
spectators.forEach(spectator -> sendMessage(spectator, message));
|
||||
}
|
||||
|
||||
private void broadcastToSpectators(BasicMessage message) {
|
||||
spectators.forEach(spectator -> sendMessage(spectator, message));
|
||||
}
|
||||
|
||||
private void broadcastToAllExcept(Participant except, BasicMessage message) {
|
||||
|
||||
if (!except.equals(player1)) sendMessage(player1, message);
|
||||
if (!except.equals(player2)) sendMessage(player2, message);
|
||||
spectators.stream().filter(spectator -> !except.equals(spectator))
|
||||
.forEach(spectator -> sendMessage(spectator, message));
|
||||
}
|
||||
|
||||
private void sendError(Participant recipient, String errorMessage) {
|
||||
sendErrorCallback.accept(recipient.getConnection(), errorMessage);
|
||||
}
|
||||
|
||||
// Methods to send events
|
||||
|
||||
public void sendEvents(Participant recipient, Event... events) {
|
||||
MessageRelay.getInstance().sendMessage(this, recipient, events);
|
||||
var message = new EventMessage();
|
||||
message.messages = events;
|
||||
|
||||
sendMessage(recipient, message);
|
||||
}
|
||||
|
||||
public void broadcastEvents(Event... events) {
|
||||
// TODO: implement
|
||||
MessageRelay.getInstance().broadcastEvents(this, events);
|
||||
var message = new EventMessage();
|
||||
message.messages = events;
|
||||
|
||||
broadcast(message);
|
||||
}
|
||||
|
||||
public void broadcastToAllExcept(Participant except, Event... events) {
|
||||
// TODO: implement
|
||||
var messageRelayInstance = MessageRelay.getInstance();
|
||||
if (except.type == ParticipantType.Spectator) {
|
||||
spectators.stream()
|
||||
.filter(spectator -> !spectator.equals(except))
|
||||
.forEach(spectator -> messageRelayInstance.sendMessage(this, spectator, events));
|
||||
messageRelayInstance.sendMessage(this, player1, events);
|
||||
messageRelayInstance.sendMessage(this, player2, events);
|
||||
} else {
|
||||
messageRelayInstance.sendMessage(this, except.equals(player1) ? player2 : player1, events);
|
||||
spectators.forEach(spectator -> messageRelayInstance.sendMessage(this, spectator, events));
|
||||
}
|
||||
var message = new EventMessage();
|
||||
message.messages = events;
|
||||
|
||||
broadcastToAllExcept(except, message);
|
||||
}
|
||||
|
||||
/** Kills all connections to client, as well as the lobby */
|
||||
/** Kills all connections to client, as well as the lobby. Notifying the thread has to be done separately. */
|
||||
public void terminateConnection() {
|
||||
// TODO: implement this
|
||||
Logger.debug("Setting termination flag for lobby '{}'", gameID);
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -323,12 +488,12 @@ public class LobbyConnection implements Runnable {
|
||||
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);
|
||||
return characterSelectionActive == that.characterSelectionActive && 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(lobby, gameID, player1, player2, characterSelection, inGame, spectators, incomingMessages);
|
||||
return Objects.hash(lobby, gameID, player1, player2, characterSelectionActive, inGame, spectators, incomingMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -338,7 +503,7 @@ public class LobbyConnection implements Runnable {
|
||||
", gameID='" + gameID + '\'' +
|
||||
", player1=" + player1 +
|
||||
", player2=" + player2 +
|
||||
", characterSelection=" + characterSelection +
|
||||
", characterSelection=" + characterSelectionActive +
|
||||
", inGame=" + inGame +
|
||||
", spectators=" + spectators +
|
||||
", incomingMessages=" + incomingMessages +
|
||||
|
Loading…
Reference in New Issue
Block a user