From c5debe13e861e3ea814f849a63033edef2ca552c Mon Sep 17 00:00:00 2001 From: Jonah Bauer Date: Tue, 1 Feb 2022 02:03:13 +0100 Subject: [PATCH] added running flag to SessionData --- .../wizard/client/libgdx/actors/IconList.java | 53 +++++++++++++++++ .../client/libgdx/screens/LobbyScreen.java | 39 +++++++++---- .../client/libgdx/screens/SessionScreen.java | 25 +++----- .../wizard/client/libgdx/state/Game.java | 1 - .../common/messages/data/SessionData.java | 4 ++ .../eu/jonahbauer/wizard/server/Session.java | 58 +++++++++++-------- .../wizard/server/debug/DebugSession.java | 4 +- 7 files changed, 125 insertions(+), 59 deletions(-) create mode 100644 wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/IconList.java diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/IconList.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/IconList.java new file mode 100644 index 0000000..cee4229 --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/IconList.java @@ -0,0 +1,53 @@ +package eu.jonahbauer.wizard.client.libgdx.actors; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.scenes.scene2d.ui.List; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.utils.Align; +import lombok.Getter; +import lombok.Setter; + +public abstract class IconList extends List { + @Getter + @Setter + private float iconWidth = -1; + + @Getter + @Setter + private float iconPadding = 8; + + @SuppressWarnings("unused") + public IconList(Skin skin) { + super(skin); + } + + @SuppressWarnings("unused") + public IconList(Skin skin, String styleName) { + super(skin, styleName); + } + + @SuppressWarnings("unused") + public IconList(ListStyle style) { + super(style); + } + + public abstract Drawable getIcon(T item); + + @Override + @Deprecated + public void setAlignment(int alignment) {} + + @Override + protected GlyphLayout drawItem(Batch batch, BitmapFont font, int index, T item, float x, float y, float width) { + var text = toString(item); + var icon = getIcon(item); + var height = font.getCapHeight(); + var iconWidth = this.iconWidth < 0 ? height : this.iconWidth; + + icon.draw(batch, x, y - height, iconWidth, height); + return font.draw(batch, text, x + iconWidth + iconPadding, y, 0, text.length(), width - iconWidth - iconPadding, Align.left, false, "..."); + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/LobbyScreen.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/LobbyScreen.java index 0dc35a5..b62bd53 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/LobbyScreen.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/LobbyScreen.java @@ -3,7 +3,10 @@ package eu.jonahbauer.wizard.client.libgdx.screens; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import eu.jonahbauer.wizard.client.libgdx.UiskinAtlas; import eu.jonahbauer.wizard.client.libgdx.WizardGame; +import eu.jonahbauer.wizard.client.libgdx.actors.IconList; import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager; import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener; import eu.jonahbauer.wizard.client.libgdx.state.Lobby; @@ -17,7 +20,6 @@ public class LobbyScreen extends MenuScreen { private TextButton buttonBack; private TextButton buttonJoin; - private TextButton buttonRejoin; private TextButton buttonCreate; private TextField playerName; @@ -26,6 +28,7 @@ public class LobbyScreen extends MenuScreen { private Label labelSessionConfiguration; private UUID selectedSession; + private boolean rejoin = false; private List sessions; private ScrollPane sessionListContainer; @@ -36,14 +39,15 @@ public class LobbyScreen extends MenuScreen { game.getClient().execute(Lobby.class, Lobby::disconnect); sfxClick(); } else if (actor == buttonJoin) { - join(); + if (rejoin) { + game.getClient().execute(Lobby.class, Lobby::showRejoinScreen); + } else { + join(); + } sfxClick(); } else if (actor == buttonCreate) { game.getClient().execute(Lobby.class, Lobby::showCreateScreen); sfxClick(); - } else if (actor == buttonRejoin) { - game.getClient().execute(Lobby.class, Lobby::showRejoinScreen); - sfxClick(); } } }; @@ -64,21 +68,26 @@ public class LobbyScreen extends MenuScreen { buttonCreate.addListener(listener); getButtonGroup().addActor(buttonCreate); - buttonRejoin = new TextButton(messages.get("menu.lobby.rejoin"), skin); - buttonRejoin.addListener(listener); - getButtonGroup().addActor(buttonRejoin); - buttonJoin = new TextButton(messages.get("menu.lobby.join"), skin); buttonJoin.addListener(listener); getButtonGroup().addActor(buttonJoin); getButtonGroup().setWidth(0.55f * WizardGame.WIDTH); - sessions = new List<>(skin) { + sessions = new IconList<>(skin) { + // TODO better icons + private final Drawable running = skin.getDrawable(UiskinAtlas.NOT_READY); + private final Drawable notRunning = skin.getDrawable(UiskinAtlas.READY); + @Override public String toString(SessionData session) { return session.getName(); } + + @Override + public Drawable getIcon(SessionData item) { + return item.isRunning() ? running : notRunning; + } }; sessions.addListener(new ChangeListener() { @Override @@ -102,12 +111,11 @@ public class LobbyScreen extends MenuScreen { stage.addActor(content); stage.addCaptureListener(new KeyboardFocusManager( - sessions, playerName, buttonBack, buttonCreate, buttonRejoin, buttonJoin + sessions, playerName, buttonBack, buttonCreate, buttonJoin )); buttonBack.setName("button_back"); buttonJoin.setName("button_join"); - buttonJoin.setName("button_rejoin"); buttonCreate.setName("button_create"); sessions.setName("session_list"); playerName.setName("player_name"); @@ -194,14 +202,21 @@ public class LobbyScreen extends MenuScreen { labelSessionPlayerCount.setText(Integer.toString(data.getPlayerCount())); labelSessionConfiguration.setText(data.getConfiguration().toString()); selectedSession = data.getUuid(); + updateRejoin(data.isRunning()); } else { labelSessionName.setText(""); labelSessionPlayerCount.setText(""); labelSessionConfiguration.setText(""); selectedSession = null; + updateRejoin(false); } } + private void updateRejoin(boolean rejoin) { + this.rejoin = rejoin; + buttonJoin.setText(messages.get("menu.lobby." + (rejoin ? "rejoin" : "join"))); + } + private void join() { boolean error = false; diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/SessionScreen.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/SessionScreen.java index ca0814d..4000428 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/SessionScreen.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/SessionScreen.java @@ -1,15 +1,12 @@ package eu.jonahbauer.wizard.client.libgdx.screens; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; import eu.jonahbauer.wizard.client.libgdx.UiskinAtlas; import eu.jonahbauer.wizard.client.libgdx.WizardGame; +import eu.jonahbauer.wizard.client.libgdx.actors.IconList; import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager; import eu.jonahbauer.wizard.client.libgdx.state.Session; import eu.jonahbauer.wizard.common.messages.data.PlayerData; @@ -60,9 +57,9 @@ public class SessionScreen extends MenuScreen { getButtonGroup().setWidth(0.55f * WizardGame.WIDTH); - players = new List<>(skin) { - private final TextureRegion ready = skin.getRegion(UiskinAtlas.READY); - private final TextureRegion notReady = skin.getRegion(UiskinAtlas.NOT_READY); + players = new IconList<>(skin) { + private final Drawable ready = skin.getDrawable(UiskinAtlas.READY); + private final Drawable notReady = skin.getDrawable(UiskinAtlas.NOT_READY); @Override public String toString(PlayerData player) { @@ -70,16 +67,8 @@ public class SessionScreen extends MenuScreen { } @Override - @SuppressWarnings("SuspiciousNameCombination") - protected GlyphLayout drawItem(Batch batch, BitmapFont font, int index, PlayerData item, float x, float y, float width) { - String string = toString(item); - var height = font.getCapHeight(); - if (item.isReady()) { - batch.draw(ready, x, y - height, height, height); - } else { - batch.draw(notReady, x, y - height, height, height); - } - return font.draw(batch, string, x + height + 8, y, 0, string.length(), width - height - 8, Align.left, false, "..."); + public Drawable getIcon(PlayerData item) { + return item.isReady() ? ready : notReady; } }; diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/state/Game.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/state/Game.java index b43041e..34a057f 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/state/Game.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/state/Game.java @@ -6,7 +6,6 @@ import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen; import eu.jonahbauer.wizard.client.libgdx.util.Pair; import eu.jonahbauer.wizard.common.messages.client.InteractionMessage; import eu.jonahbauer.wizard.common.messages.data.PlayerData; -import eu.jonahbauer.wizard.common.messages.data.SessionData; import eu.jonahbauer.wizard.common.messages.observer.*; import eu.jonahbauer.wizard.common.messages.player.*; import eu.jonahbauer.wizard.common.messages.server.AckMessage; diff --git a/wizard-common/src/main/java/eu/jonahbauer/wizard/common/messages/data/SessionData.java b/wizard-common/src/main/java/eu/jonahbauer/wizard/common/messages/data/SessionData.java index d353427..f45bd25 100644 --- a/wizard-common/src/main/java/eu/jonahbauer/wizard/common/messages/data/SessionData.java +++ b/wizard-common/src/main/java/eu/jonahbauer/wizard/common/messages/data/SessionData.java @@ -26,4 +26,8 @@ public class SessionData { * Configuration of the session */ private final @NonNull Configuration configuration; + /** + * Whether the session is running. + */ + private final boolean running; } diff --git a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java index f98b8d6..4257e12 100644 --- a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java +++ b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java @@ -53,6 +53,11 @@ public class Session implements Observer, SessionMBean { this.configuration = configuration; } + @Override + public boolean isRunning() { + return game != null; + } + /** * Associates the given player with this session and notifies all other players in the * session with a {@link PlayerJoinedMessage}, the joining player with a {@link SessionJoinedMessage} and all @@ -63,7 +68,7 @@ public class Session implements Observer, SessionMBean { * @return the players uuid */ public synchronized UUID join(Player player, String name) { - if (game != null) { + if (isRunning()) { throw new NackException(NackMessage.GAME_ALREADY_STARTED, "Game has already started."); } else if (players.size() == MAX_PLAYERS) { throw new NackException(NackMessage.SESSION_FULL, "Session is full."); @@ -80,7 +85,7 @@ public class Session implements Observer, SessionMBean { sessionPlayer.setPlayer(player); notifyJoined(sessionPlayer.toData()); - Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData())); + notifyLobby(); return sessionPlayer.getUuid(); } @@ -115,13 +120,13 @@ public class Session implements Observer, SessionMBean { } public synchronized void leave(UUID player) { - if (game == null) { + if (!isRunning()) { if (players.remove(player) != null) { if (players.size() == 0) { Lobby.getInstance().removeSession(uuid); } else { notifyPlayers(new PlayerLeftMessage(player)); - Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData())); + notifyLobby(); } } } else { @@ -139,7 +144,7 @@ public class Session implements Observer, SessionMBean { var player = players.get(uuid); if (player == null) { throw new NackException(NackMessage.PLAYER_NOT_FOUND, "Who are you?"); - } else if (game != null) { + } else if (isRunning()) { throw new NackException(NackMessage.GAME_ALREADY_STARTED, "Game has already started."); } @@ -164,7 +169,7 @@ public class Session implements Observer, SessionMBean { var player = players.get(uuid); if (player == null) { throw new NackException(NackMessage.PLAYER_NOT_FOUND, "Who are you?"); - } else if (game == null) { + } else if (!isRunning()) { throw new NackException(NackMessage.GAME_NOT_YET_STARTED, "Game hat not yet started."); } else { try { @@ -178,10 +183,11 @@ public class Session implements Observer, SessionMBean { } } - protected void startGame() { + protected synchronized void startGame() { notifyPlayers(new StartingGameMessage()); messages.add(Pair.of(null, new StartingGameMessage())); game = new Game(configuration, timeout, 10 * 60 * 1000, this); + notifyLobby(); game.start(List.copyOf(players.keySet())); CompletableFuture.runAsync(() -> { while (true) { @@ -195,20 +201,23 @@ public class Session implements Observer, SessionMBean { break; } } - players.forEach((id, player) -> player.setReady(false)); - synchronized (this) { - game = null; - messages.clear(); - for (SessionPlayer player : List.copyOf(players.values())) { - if (!player.isConnected()) { - leave(player.getUuid()); - } - } - } + finishGame(); }); } - protected void notifyJoined(PlayerData joined) { + protected synchronized void finishGame() { + players.forEach((id, player) -> player.setReady(false)); + game = null; + messages.clear(); + for (SessionPlayer player : List.copyOf(players.values())) { + if (!player.isConnected()) { + leave(player.getUuid()); + } + } + notifyLobby(); + } + + protected synchronized void notifyJoined(PlayerData joined) { var message = new PlayerJoinedMessage(joined); for (SessionPlayer player : players.values()) { if (player.getUuid().equals(joined.getUuid())) { @@ -224,14 +233,14 @@ public class Session implements Observer, SessionMBean { } } - protected void notifyPlayers(ServerMessage message) { + protected synchronized void notifyPlayers(ServerMessage message) { for (SessionPlayer player : players.values()) { player.send(message); } } public SessionData toData() { - return new SessionData(uuid, name, players.size(), configuration); + return new SessionData(uuid, name, players.size(), configuration, isRunning()); } @Override @@ -266,6 +275,10 @@ public class Session implements Observer, SessionMBean { } } + protected void notifyLobby() { + Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData())); + } + public void close() { for (var sessionPlayer : getPlayers().values()) { var player = sessionPlayer.getPlayer(); @@ -276,11 +289,6 @@ public class Session implements Observer, SessionMBean { } // - @Override - public boolean isRunning() { - return game != null; - } - public boolean isDebug() { return false; } diff --git a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/debug/DebugSession.java b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/debug/DebugSession.java index 2aceaa0..bcf79ee 100644 --- a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/debug/DebugSession.java +++ b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/debug/DebugSession.java @@ -3,9 +3,7 @@ package eu.jonahbauer.wizard.server.debug; import eu.jonahbauer.wizard.common.messages.player.PlayerMessage; import eu.jonahbauer.wizard.common.messages.server.NackMessage; import eu.jonahbauer.wizard.common.messages.server.ServerMessage; -import eu.jonahbauer.wizard.common.messages.server.SessionModifiedMessage; import eu.jonahbauer.wizard.common.model.Configuration; -import eu.jonahbauer.wizard.server.Lobby; import eu.jonahbauer.wizard.server.NackException; import eu.jonahbauer.wizard.server.Session; import eu.jonahbauer.wizard.server.machine.Player; @@ -51,7 +49,7 @@ public class DebugSession extends Session { sessionPlayer.setPlayer(player); notifyJoined(sessionPlayer.toData()); - Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData())); + notifyLobby(); return sessionPlayer.getUuid(); }