fix: destroy lobbies properly after ended games and during grouping
This commit is contained in:
parent
ec6236c57f
commit
f8aa2c9bf2
@ -56,7 +56,7 @@ public class TurnTimeoutTimer {
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
Logger.trace("Clearing timer");
|
Logger.trace("Clearing timer");
|
||||||
if (this.current != null) {
|
if (this.current != null) {
|
||||||
current.cancel(false);
|
current.cancel(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,8 @@ public class LobbyConnection implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
|
LobbyRunner.getInstance().removeLobby(this);
|
||||||
|
LobbyManager.getInstance().removeLobby(gameID);
|
||||||
state = LobbyConnectionState.Aborted;
|
state = LobbyConnectionState.Aborted;
|
||||||
removeParticipant(player1);
|
removeParticipant(player1);
|
||||||
removeParticipant(player2);
|
removeParticipant(player2);
|
||||||
|
@ -38,15 +38,19 @@ public class LobbyManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a newly connected Client, and returns whether the game is already running in the given {@link
|
* Handles a newly connected Client, and returns whether the game is already running in the given {@link
|
||||||
* AtomicBoolean}
|
* AtomicBoolean}.
|
||||||
*/
|
*/
|
||||||
public boolean handleConnect(Client client, AtomicBoolean running) {
|
public boolean handleConnect(Client client, AtomicBoolean running) {
|
||||||
if (participants.containsKey(client.getId())) {
|
Logger.debug("Connecting new client");
|
||||||
LobbyConnection lobby = lobbies.get(participants.get(client.getId()).lobby);
|
|
||||||
|
Participant participant = participants.get(client.getId());
|
||||||
|
if (participant != null) {
|
||||||
|
LobbyConnection lobby = lobbies.get(participant.lobby);
|
||||||
if (lobby != null) {
|
if (lobby != null) {
|
||||||
running.set(lobby.state == LobbyConnectionState.Started);
|
running.set(lobby.state == LobbyConnectionState.Started);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +60,7 @@ public class LobbyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addParticipant(client, client.socket.getResourceDescriptor(), message.role);
|
addParticipant(client, client.socket.getResourceDescriptor(), message.role);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,62 +83,6 @@ public class LobbyManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a participant to a lobby. If the maximum amount of lobbies is already filled, or if the lobby requested
|
|
||||||
* isn't free, the participant is disconnected.
|
|
||||||
*/
|
|
||||||
private void addParticipant(Client client, String lobbyID, RoleEnum role) {
|
|
||||||
Logger.trace("Adding participant '{}' to the lobby '{}'", client.getId().getName(), lobbyID);
|
|
||||||
if (!lobbies.containsKey(lobbyID)) {
|
|
||||||
if (!LobbyRunner.getInstance().canAddLobby()) {
|
|
||||||
Logger.info("Rejecting participant '{}' as server is already full", client.getId().getName());
|
|
||||||
UserManager.getInstance().removeClient(client, "The server has currently its maximum" +
|
|
||||||
"lobby number. Please connect as a spectator instead.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Logger.info("Lobby '{}' didn't exist yet, initializing", lobbyID);
|
|
||||||
lobbies.put(lobbyID, new LobbyConnection(lobbyID));
|
|
||||||
}
|
|
||||||
|
|
||||||
LobbyConnection lobby = lobbies.get(lobbyID);
|
|
||||||
|
|
||||||
if (!lobby.hasFreePlayerSlot() && role != RoleEnum.SPECTATOR) {
|
|
||||||
Logger.debug("No free player slots available, disconnecting client '{}'", client.getId().getName());
|
|
||||||
UserManager.getInstance()
|
|
||||||
.removeClient(client, "The lobby your requested is already full. " +
|
|
||||||
"Please connect as a spectator instead.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParticipantType type;
|
|
||||||
|
|
||||||
if (role == RoleEnum.SPECTATOR) {
|
|
||||||
type = ParticipantType.Spectator;
|
|
||||||
} else {
|
|
||||||
type = lobby.freeSlot();
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.trace("New participant '{}' has the role '{}'", client.getId().getName(), type);
|
|
||||||
|
|
||||||
Participant participant = new Participant(client, lobbyID, type);
|
|
||||||
participants.put(client.getId(), participant);
|
|
||||||
|
|
||||||
lobby.addParticipant(participant);
|
|
||||||
|
|
||||||
if (type != ParticipantType.Spectator) {
|
|
||||||
Logger.debug("Sending GameAssignment message to user '{}'", client.getId().getName());
|
|
||||||
GameAssignmentMessage response = new GameAssignmentMessage();
|
|
||||||
response.gameID = lobby.gameID;
|
|
||||||
response.characterSelection = lobby.options.get(type);
|
|
||||||
participant.sendMessage(response);
|
|
||||||
} else {
|
|
||||||
Logger.debug("Sending GeneralAssignment message to user '{}'", client.getId().getName());
|
|
||||||
GeneralAssignmentMessage response = new GeneralAssignmentMessage();
|
|
||||||
response.gameID = lobby.gameID;
|
|
||||||
participant.sendMessage(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a {@link CharacterSelectionMessage}, computes the characters that have been selected and relays that
|
* Handles a {@link CharacterSelectionMessage}, computes the characters that have been selected and relays that
|
||||||
* information to the {@link LobbyConnection} concerned by this information.
|
* information to the {@link LobbyConnection} concerned by this information.
|
||||||
@ -228,27 +177,90 @@ public class LobbyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the disconnect of a WebSocket. Note that this is not a leave from the game, but instead just that:
|
* Handles the disconnect of a WebSocket.
|
||||||
* a reconnectable disconnect.
|
|
||||||
*/
|
*/
|
||||||
public void handleDisconnect(Client client, boolean byRemote) {
|
public void handleDisconnect(Client client, boolean byRemote) {
|
||||||
Logger.trace("Handling disconnect of Client");
|
Logger.trace("Handling disconnect of Client");
|
||||||
|
|
||||||
if (!participants.containsKey(client.getId())) {
|
if (!participants.containsKey(client.getId())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Participant participant = participants.get(client.getId());
|
Participant participant = participants.get(client.getId());
|
||||||
|
|
||||||
LobbyConnection lobby = lobbies.get(participant.lobby);
|
LobbyConnection lobby = lobbies.get(participant.lobby);
|
||||||
|
|
||||||
if (lobby == null) {
|
if (lobby == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(lobby.state == LobbyConnectionState.Started) {
|
||||||
lobby.handleDisconnect(participant);
|
lobby.handleDisconnect(participant);
|
||||||
|
|
||||||
|
}else {
|
||||||
|
Logger.debug("Deleting participant after leaving a non-started lobby");
|
||||||
|
participants.remove(client.getId());
|
||||||
|
|
||||||
|
if(lobby.hasFreePlayerSlot()) {
|
||||||
|
Logger.debug("Destroying lobby after last player left");
|
||||||
|
lobby.terminate();
|
||||||
|
lobbies.remove(participant.lobby);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void removeLobby(String lobbyID) {
|
||||||
|
lobbies.remove(lobbyID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a participant to a lobby. If the maximum amount of lobbies is already filled, or if the lobby requested
|
||||||
|
* isn't free, the participant is disconnected.
|
||||||
|
*/
|
||||||
|
private void addParticipant(Client client, String lobbyID, RoleEnum role) {
|
||||||
|
Logger.trace("Adding participant '{}' to the lobby '{}'", client.getId(), lobbyID);
|
||||||
|
|
||||||
|
if (!lobbies.containsKey(lobbyID)) {
|
||||||
|
if (!LobbyRunner.getInstance().canAddLobby()) {
|
||||||
|
Logger.info("Rejecting participant '{}' as server is already full", client.getId());
|
||||||
|
UserManager.getInstance().removeClient(client, "The server is currently full. Please connect as a spectator instead.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Logger.info("Lobby '{}' didn't exist yet, initializing", lobbyID);
|
||||||
|
lobbies.put(lobbyID, new LobbyConnection(lobbyID));
|
||||||
|
}
|
||||||
|
|
||||||
|
LobbyConnection lobby = lobbies.get(lobbyID);
|
||||||
|
|
||||||
|
if (!lobby.hasFreePlayerSlot() && role != RoleEnum.SPECTATOR) {
|
||||||
|
Logger.debug("No free player slots available, disconnecting client '{}'", client.getId());
|
||||||
|
UserManager.getInstance().removeClient(client, "The lobby your requested is already full. Please connect as a spectator instead.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticipantType type = lobby.freeSlot();
|
||||||
|
|
||||||
|
Logger.trace("New participant '{}' has the role '{}'", client.getId(), type);
|
||||||
|
|
||||||
|
Participant participant = new Participant(client, lobbyID, type);
|
||||||
|
participants.put(client.getId(), participant);
|
||||||
|
|
||||||
|
lobby.addParticipant(participant);
|
||||||
|
|
||||||
|
if (type != ParticipantType.Spectator) {
|
||||||
|
Logger.debug("Sending GameAssignment message to user '{}'", client.getId());
|
||||||
|
GameAssignmentMessage response = new GameAssignmentMessage();
|
||||||
|
response.gameID = lobby.gameID;
|
||||||
|
response.characterSelection = lobby.options.get(type);
|
||||||
|
participant.sendMessage(response);
|
||||||
|
} else {
|
||||||
|
Logger.debug("Sending GeneralAssignment message to user '{}'", client.getId());
|
||||||
|
GeneralAssignmentMessage response = new GeneralAssignmentMessage();
|
||||||
|
response.gameID = lobby.gameID;
|
||||||
|
participant.sendMessage(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a participant from the game entirely. This is done when for example a player gets removed from the
|
* Removes a participant from the game entirely. This is done when for example a player gets removed from the
|
||||||
* Lobby because of a timeout.
|
* Lobby because of a timeout.
|
||||||
|
@ -4,7 +4,6 @@ import org.tinylog.Logger;
|
|||||||
import uulm.teamname.marvelous.server.Server;
|
import uulm.teamname.marvelous.server.Server;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class meant for running lobbies. It manages said lobbies, creates threads for it, and moves it into an executor
|
* Class meant for running lobbies. It manages said lobbies, creates threads for it, and moves it into an executor
|
||||||
@ -54,7 +53,6 @@ public class LobbyRunner {
|
|||||||
Logger.warn("Tried to remove non-existent lobby thread. This is probably a bug.");
|
Logger.warn("Tried to remove non-existent lobby thread. This is probably a bug.");
|
||||||
} else {
|
} else {
|
||||||
Logger.debug("Stopping and removing lobby '{}'", lobby.gameID);
|
Logger.debug("Stopping and removing lobby '{}'", lobby.gameID);
|
||||||
lobby.terminate();
|
|
||||||
activeLobbies.remove(lobby);
|
activeLobbies.remove(lobby);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,6 @@ public class SUID {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SUID{" +
|
return name + "#" + deviceID;
|
||||||
"name='" + name + '\'' +
|
|
||||||
", deviceID='" + deviceID + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class UserManager {
|
|||||||
this.json = new JSON(Server.getCharacterConfig());
|
this.json = new JSON(Server.getCharacterConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called on a new WebSocket connection. Places the WebSocket and its ResourceDescriptor in a HashMap. */
|
/** Called on a new WebSocket connection. */
|
||||||
public void connectUser(WebSocket conn) {
|
public void connectUser(WebSocket conn) {
|
||||||
Logger.debug("Connected new user");
|
Logger.debug("Connected new user");
|
||||||
synchronized(clients) {
|
synchronized(clients) {
|
||||||
|
Loading…
Reference in New Issue
Block a user