improved error handling

main
Jonah Bauer 3 years ago
parent eef8f4ac40
commit 7649ff0b2c

@ -23,7 +23,7 @@ public class Client extends TimeoutContext<ClientState, Client> {
@Getter @Getter
@Setter @Setter
public boolean isError = false; private boolean error = false;
public Client(WizardGame game) { public Client(WizardGame game) {
super(new Menu()); super(new Menu());

@ -5,56 +5,35 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.WizardGame; import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager; import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager;
import eu.jonahbauer.wizard.client.libgdx.state.BaseState; import eu.jonahbauer.wizard.client.libgdx.state.BaseState;
import eu.jonahbauer.wizard.client.libgdx.state.Lobby;
import eu.jonahbauer.wizard.client.libgdx.state.Session;
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
public class ErrorScreen extends MenuScreen { public class ErrorScreen extends MenuScreen {
private final String labelText; private final String message;
private TextButton buttonBack; private TextButton buttonBack;
private final ChangeListener listener = new ChangeListener() { private final ChangeListener listener = new ChangeListener() {
@Override @Override
public void changed(ChangeEvent event, Actor actor) { public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonBack) { if (actor == buttonBack) {
game.getClient().execute(BaseState.class, BaseState::dismissErrorScreen);
sfxClick(); sfxClick();
} }
} }
}; };
public ErrorScreen(WizardGame game, Client client, NackMessage message) { public ErrorScreen(WizardGame game, String message) {
super(game); super(game);
labelText = switch (message.getCode()) { this.message = message;
case NackMessage.GAME_ALREADY_STARTED -> messages.get("menu.error.game_already_started");
case NackMessage.SESSION_FULL -> messages.get("menu.error.session_full");
case NackMessage.SESSION_NOT_FOUND -> messages.get("menu.error.session_not_found");
case NackMessage.PLAYER_NAME_TAKEN -> messages.get("menu.error.player_name_taken");
case NackMessage.PLAYER_NAME_NOT_ALLOWED -> messages.get("menu.error.player_name_not_allowed");
case NackMessage.SESSION_NAME_TAKEN -> messages.get("menu.error.session_name_taken");
case NackMessage.SESSION_NAME_NOT_ALLOWED -> messages.get("menu.error.session_name_not_allowed");
case NackMessage.MALFORMED_MESSAGE -> messages.get("menu.error.malformed_message");
case NackMessage.UNEXPECTED_MESSAGE -> messages.get("menu.error.unexpected_message");
case NackMessage.ILLEGAL_ARGUMENT -> messages.get("menu.error.illegal_argument");
case NackMessage.NOT_FOUND -> messages.get("menu.error.not_found");
case NackMessage.ALREADY_CONNECTED -> messages.get("menu.error.already_connected");
case NackMessage.GAME_NOT_YET_STARTED -> messages.get("menu.error.game_not_yet_started");
case NackMessage.PLAYER_NOT_FOUND -> messages.get("menu.error.player_not_found");
case NackMessage.ILLEGAL_STATE -> messages.get("menu.error.illegal_state");
case NackMessage.BAD_REQUEST -> messages.get("menu.error.bad_request");
default -> "Something went terribly wrong :(";
};
} }
@Override @Override
public void show() { public void show() {
super.show(); super.show();
var buttonBack = new TextButton(messages.get("menu.error.back"), skin); buttonBack = new TextButton(messages.get("menu.error.back"), skin);
var label = new Label(labelText, skin); var label = new Label(message, skin);
var content = new VerticalGroup(); var content = new VerticalGroup();
content.setPosition(WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT*0.5f); content.setPosition(WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT*0.5f);

@ -7,7 +7,6 @@ import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager; import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager;
import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener; import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener;
import eu.jonahbauer.wizard.client.libgdx.state.Lobby; import eu.jonahbauer.wizard.client.libgdx.state.Lobby;
import eu.jonahbauer.wizard.client.libgdx.state.Menu;
import eu.jonahbauer.wizard.common.messages.data.SessionData; import eu.jonahbauer.wizard.common.messages.data.SessionData;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;

@ -1,23 +1,19 @@
package eu.jonahbauer.wizard.client.libgdx.state; package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.MustBeInvokedByOverriders;
import java.util.Optional; import java.util.Optional;
@Log4j2 @Log4j2
public abstract class Awaiting extends BaseState implements ClientState { public abstract class Awaiting extends BaseState implements ClientState {
private static final int TIMEOUT_MILLIS = 10_000; private static final int TIMEOUT_MILLIS = 10_000;
@Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) {
return unexpectedMessage(message);
}
@Override @Override
@SneakyThrows @SneakyThrows
@MustBeInvokedByOverriders
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
client.timeout(this, TIMEOUT_MILLIS); client.timeout(this, TIMEOUT_MILLIS);
return Optional.empty(); return Optional.empty();

@ -2,6 +2,7 @@ package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.screens.LoadingScreen; import eu.jonahbauer.wizard.client.libgdx.screens.LoadingScreen;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import java.util.Optional; import java.util.Optional;
@ -12,22 +13,35 @@ public final class AwaitingConnection extends Awaiting {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
log.info("Awaiting connection..."); log.info("Awaiting connection...");
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.connecting")); if (!client.isError()) showScreen(client);
return super.onEnter(client); return super.onEnter(client);
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
showScreen(client);
return Optional.empty();
}
@Override @Override
public Optional<ClientState> onOpen(Client client) { public Optional<ClientState> onOpen(Client client) {
log.info("Connection established."); log.info("Connection established.");
return Optional.of(new AwaitingJoinLobby()); return Optional.of(new AwaitingJoinLobby());
} }
@Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) {
return unexpectedMessage(client, message);
}
@Override @Override
public Optional<ClientState> onClose(Client client, int code, String reason, boolean remote) { public Optional<ClientState> onClose(Client client, int code, String reason, boolean remote) {
// TODO user feedback
log.error("Connection could not be established. (code={}, reason={}, remote={})", code, reason, remote); log.error("Connection could not be established. (code={}, reason={}, remote={})", code, reason, remote);
showErrorScreen(client, "Connection could not be established. (code=%d, reason=%s, remote=%b)".formatted(code, reason, remote));
return Optional.of(new Menu()); return Optional.of(new Menu());
} }
//public Optional<ClientState> showErrorScreen(Client client, ) private void showScreen(Client client) {
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.connecting"));
}
} }

@ -32,11 +32,17 @@ public final class AwaitingGameLog extends BaseState {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
log.info("Waiting for game log..."); log.info("Waiting for game log...");
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.rejoining")); if (!client.isError()) showScreen(client);
client.timeout(this, TIMEOUT_MILLIS); client.timeout(this, TIMEOUT_MILLIS);
return Optional.empty(); return Optional.empty();
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
showScreen(client);
return Optional.empty();
}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (!started) { if (!started) {
@ -44,7 +50,7 @@ public final class AwaitingGameLog extends BaseState {
started = true; started = true;
return Optional.empty(); return Optional.empty();
} else { } else {
return unexpectedMessage(message); return unexpectedMessage(client, message);
} }
} else if (message instanceof GameMessage gameMessage) { } else if (message instanceof GameMessage gameMessage) {
messages.add(gameMessage.getObserverMessage()); messages.add(gameMessage.getObserverMessage());
@ -54,7 +60,11 @@ public final class AwaitingGameLog extends BaseState {
game.init(messages); game.init(messages);
return Optional.of(game); return Optional.of(game);
} else { } else {
return unexpectedMessage(message); return unexpectedMessage(client, message);
} }
} }
private void showScreen(Client client) {
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.rejoining"));
}
} }

@ -14,17 +14,27 @@ public final class AwaitingJoinLobby extends Awaiting {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
log.info("Waiting for session list..."); log.info("Waiting for session list...");
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.joining_lobby")); if (!client.isError()) showScreen(client);
return super.onEnter(client); return super.onEnter(client);
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
showScreen(client);
return Optional.empty();
}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof SessionListMessage list) { if (message instanceof SessionListMessage list) {
log.info("There are {} open sessions.", list.getSessions().size()); log.info("There are {} open sessions.", list.getSessions().size());
return Optional.of(new Lobby(list.getSessions())); return Optional.of(new Lobby(list.getSessions()));
} else { } else {
return super.onMessage(client, message); return unexpectedMessage(client, message);
} }
} }
private void showScreen(Client client) {
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.joining_lobby"));
}
} }

@ -29,16 +29,22 @@ public final class AwaitingJoinSession extends Awaiting {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
log.info("Waiting for acknowledgment..."); log.info("Waiting for acknowledgment...");
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.joining_session")); if (!client.isError()) showScreen(client);
return super.onEnter(client); return super.onEnter(client);
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
showScreen(client);
return Optional.empty();
}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof SessionJoinedMessage joined) { if (message instanceof SessionJoinedMessage joined) {
var session = joined.getSession(); var session = joined.getSession();
if (this.session != null && !this.session.equals(session)) { if (this.session != null && !this.session.equals(session)) {
return super.onMessage(client, message); return unexpectedMessage(client, message);
} else { } else {
var players = joined.getPlayers(); var players = joined.getPlayers();
var player = joined.getPlayer(); var player = joined.getPlayer();
@ -79,16 +85,21 @@ public final class AwaitingJoinSession extends Awaiting {
case NackMessage.SESSION_NAME_NOT_ALLOWED -> log.error("Session name not allowed."); case NackMessage.SESSION_NAME_NOT_ALLOWED -> log.error("Session name not allowed.");
default -> log.error("Nack {}: {}", nack.getCode(), nack.getMessage()); default -> log.error("Nack {}: {}", nack.getCode(), nack.getMessage());
} }
showErrorScreen(client, nack.getMessage());
return Optional.of(new AwaitingJoinLobby()); return Optional.of(new AwaitingJoinLobby());
} else if (message instanceof SessionModifiedMessage || message instanceof SessionRemovedMessage) { } else if (message instanceof SessionModifiedMessage || message instanceof SessionRemovedMessage) {
// drop // drop
log.debug("Dropped message {}.", message); log.debug("Dropped message {}.", message);
return Optional.empty(); return Optional.empty();
} else { } else {
return super.onMessage(client, message); return unexpectedMessage(client, message);
} }
} }
private void showScreen(Client client) {
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.joining_session"));
}
public enum Source { public enum Source {
JOIN, CREATE, REJOIN JOIN, CREATE, REJOIN
} }

@ -3,7 +3,6 @@ package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.WizardGame; import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.screens.ErrorScreen; import eu.jonahbauer.wizard.client.libgdx.screens.ErrorScreen;
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage; import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
@ -32,17 +31,24 @@ public abstract class BaseState implements ClientState {
return Optional.of(new Menu()); return Optional.of(new Menu());
} }
protected static Optional<ClientState> unexpectedMessage(ServerMessage message) { protected Optional<ClientState> unexpectedMessage(Client client, ServerMessage message) {
// return to menu on unexpected message // return to menu on unexpected message
log.fatal("Unexpected message {}. Returning to menu.", message); log.fatal("Unexpected message {}. Returning to menu.", message);
showErrorScreen(client, "Unexpected message %s. Returning to menu.".formatted(message));
return Optional.of(new Menu()); return Optional.of(new Menu());
} }
public Optional<ClientState> showErrorScreen(Client client, NackMessage nack) { @Deprecated
public void showErrorScreen(Client client, String message) {
WizardGame game = client.getGame(); WizardGame game = client.getGame();
client.setError(true); client.setError(true);
game.setScreen(new ErrorScreen(game, client, nack)); game.setScreen(new ErrorScreen(game, message));
return Optional.of(new Menu(client));
} }
public Optional<ClientState> dismissErrorScreen(Client client) {
client.setError(false);
return onErrorDismissed(client);
}
protected abstract Optional<ClientState> onErrorDismissed(Client client);
} }

@ -76,7 +76,7 @@ public final class Game extends BaseState {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
var out = handlePendingMessages(); var out = handlePendingMessages(client);
if (out.isPresent()) return out; if (out.isPresent()) return out;
gameScreen = new GameScreen(client.getGame(), self, players); gameScreen = new GameScreen(client.getGame(), self, players);
@ -85,44 +85,47 @@ public final class Game extends BaseState {
return super.onEnter(client); return super.onEnter(client);
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
return Optional.of(new Menu());
}
//<editor-fold desc="onMessage"> //<editor-fold desc="onMessage">
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
try { try {
if (message instanceof GameMessage game) { if (message instanceof GameMessage game) {
var observerMessage = game.getObserverMessage(); var observerMessage = game.getObserverMessage();
return onMessage(observerMessage); return onMessage(client, observerMessage);
} else if (message instanceof NackMessage nack) { } else if (message instanceof NackMessage nack) {
return onNackMessage(nack); return onNackMessage(client, nack);
} else if (message instanceof AckMessage) { } else if (message instanceof AckMessage) {
onAckMessage(); onAckMessage();
return Optional.empty(); return Optional.empty();
} else { } else {
return unexpectedMessage(message); return unexpectedMessage(client, message);
} }
} finally { } finally {
executeDelayedFinishInteraction(); executeDelayedFinishInteraction();
} }
} }
private Optional<ClientState> onMessage(ObserverMessage message) { private Optional<ClientState> onMessage(Client client, ObserverMessage message) {
if (finishing != 0) return onMessageWhileFinishing(message); if (finishing != 0) return onMessageWhileFinishing(client, message);
if (message instanceof StateMessage state) { if (message instanceof StateMessage state) {
switch (state.getState()) { switch (state.getState()) {
case "starting_round" -> { case "starting_round" -> {
return onStartRound(); return onStartRound(client);
} }
case "starting_trick" -> onStartTrick(); case "starting_trick" -> onStartTrick();
case "juggling" -> onJuggle(); case "juggling" -> onJuggle();
case "finishing_round" -> onFinishingRound(); case "finishing_round" -> onFinishingRound();
case "finished" -> { case "finished" -> {
onFinished(); return onFinished();
return returnToSession();
} }
case "error" -> { case "error" -> {
onError(); return onError(client);
return returnToSession();
} }
} }
} else if (message instanceof HandMessage hand) { } else if (message instanceof HandMessage hand) {
@ -142,12 +145,12 @@ public final class Game extends BaseState {
} else if (message instanceof TimeoutMessage) { } else if (message instanceof TimeoutMessage) {
onTimeoutMessage(); onTimeoutMessage();
} else { } else {
return unexpectedMessage(new GameMessage(message)); return unexpectedMessage(client, new GameMessage(message));
} }
return Optional.empty(); return Optional.empty();
} }
private Optional<ClientState> onMessageWhileFinishing(ObserverMessage message) { private Optional<ClientState> onMessageWhileFinishing(Client client, ObserverMessage message) {
if (finishing == 1) { // last "finishing_round" has been received if (finishing == 1) { // last "finishing_round" has been received
if (message instanceof ScoreMessage score) { if (message instanceof ScoreMessage score) {
onScoreMessage(score.getPoints(), false); onScoreMessage(score.getPoints(), false);
@ -166,13 +169,13 @@ public final class Game extends BaseState {
} }
} }
return unexpectedMessage(new GameMessage(message)); return unexpectedMessage(client, new GameMessage(message));
} }
private Optional<ClientState> onStartRound() { private Optional<ClientState> onStartRound(Client client) {
if (isLastRound()) { if (isLastRound()) {
log.fatal("Cannot start round {} with {} players", round + 1, players.size()); log.fatal("Cannot start round {} with {} players", round + 1, players.size());
return unexpectedMessage(new GameMessage(new StateMessage("starting_round"))); return unexpectedMessage(client, new GameMessage(new StateMessage("starting_round")));
} }
log.info("Round {} is starting...", round + 1); log.info("Round {} is starting...", round + 1);
@ -204,15 +207,18 @@ public final class Game extends BaseState {
if (isLastRound()) finishing = 1; // start finish procedure if (isLastRound()) finishing = 1; // start finish procedure
} }
private void onFinished() { private Optional<ClientState> onFinished() {
log.info("The game has finished."); log.info("The game has finished.");
if (gameScreen != null) { if (gameScreen != null) {
gameScreen.showScoreOverlay(true); gameScreen.showScoreOverlay(true);
} }
return returnToSession();
} }
private void onError() { private Optional<ClientState> onError(Client client) {
log.error("The game has finished with an error."); log.error("The game has finished with an error.");
showErrorScreen(client, "The game has finished with an error.");
return returnToSession();
} }
private void onHandMessage(@NotNull UUID player, @Unmodifiable @NotNull List<@NotNull Card> hand) { private void onHandMessage(@NotNull UUID player, @Unmodifiable @NotNull List<@NotNull Card> hand) {
@ -332,7 +338,7 @@ public final class Game extends BaseState {
if (gameScreen != null) gameScreen.timeout(); if (gameScreen != null) gameScreen.timeout();
} }
private Optional<ClientState> onNackMessage(@NotNull NackMessage nack) { private Optional<ClientState> onNackMessage(Client client, @NotNull NackMessage nack) {
sending.set(false); sending.set(false);
if (isActive() && currentInteraction.action() == JUGGLE_CARD && juggleCard != null) { if (isActive() && currentInteraction.action() == JUGGLE_CARD && juggleCard != null) {
@ -348,7 +354,7 @@ public final class Game extends BaseState {
} }
return Optional.empty(); return Optional.empty();
} else { } else {
return unexpectedMessage(nack); return unexpectedMessage(client, nack);
} }
} }
@ -514,10 +520,10 @@ public final class Game extends BaseState {
} }
//</editor-fold> //</editor-fold>
private Optional<ClientState> handlePendingMessages() { private Optional<ClientState> handlePendingMessages(Client client) {
if (pendingMessages != null) { if (pendingMessages != null) {
for (var message : pendingMessages) { for (var message : pendingMessages) {
var result = onMessage(message); var result = onMessage(client, message);
if (result.isPresent()) { if (result.isPresent()) {
return result; return result;
} }

@ -1,7 +1,6 @@
package eu.jonahbauer.wizard.client.libgdx.state; package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.screens.*; import eu.jonahbauer.wizard.client.libgdx.screens.*;
import eu.jonahbauer.wizard.common.messages.client.CreateSessionMessage; import eu.jonahbauer.wizard.common.messages.client.CreateSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.JoinSessionMessage; import eu.jonahbauer.wizard.common.messages.client.JoinSessionMessage;
@ -17,8 +16,6 @@ import static eu.jonahbauer.wizard.client.libgdx.state.AwaitingJoinSession.Sourc
public final class Lobby extends BaseState { public final class Lobby extends BaseState {
private final Map<UUID, SessionData> sessions = new HashMap<>(); private final Map<UUID, SessionData> sessions = new HashMap<>();
private Client client;
private LobbyScreen lobbyScreen; private LobbyScreen lobbyScreen;
@ -28,11 +25,16 @@ public final class Lobby extends BaseState {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
showListScreen(client); if (!client.isError()) showListScreen(client);
this.client = client;
return super.onEnter(client); return super.onEnter(client);
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
showListScreen(client);
return Optional.empty();
}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof SessionCreatedMessage created) { if (message instanceof SessionCreatedMessage created) {
@ -63,7 +65,7 @@ public final class Lobby extends BaseState {
} }
return Optional.empty(); return Optional.empty();
} else { } else {
return unexpectedMessage(message); return unexpectedMessage(client, message);
} }
} }

@ -22,17 +22,16 @@ public final class Menu extends BaseState {
if (client.getSocket() != null && client.getSocket().isOpen()) { if (client.getSocket() != null && client.getSocket().isOpen()) {
client.getSocket().close(CloseFrame.GOING_AWAY); client.getSocket().close(CloseFrame.GOING_AWAY);
} }
if (!client.isError()) showMenuScreen(client);
return super.onEnter(client); return super.onEnter(client);
} }
public Menu(Client client) { @Override
if(client.isError) { public Optional<ClientState> onErrorDismissed(Client client) {
//showErrorScreen(client); showMenuScreen(client);
} return Optional.empty();
} }
public Menu() {}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
// it is possible that there are messages still queued after // it is possible that there are messages still queued after

@ -50,6 +50,12 @@ public final class Session extends BaseState {
return super.onEnter(client); return super.onEnter(client);
} }
@Override
public Optional<ClientState> onErrorDismissed(Client client) {
showInfoScreen(client);
return Optional.empty();
}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof PlayerJoinedMessage join) { if (message instanceof PlayerJoinedMessage join) {
@ -90,7 +96,7 @@ public final class Session extends BaseState {
sessionScreen.setSending(false); sessionScreen.setSending(false);
return Optional.empty(); return Optional.empty();
} else { } else {
return unexpectedMessage(message); return unexpectedMessage(client, message);
} }
} }

Loading…
Cancel
Save