Compare commits
5 Commits
854e2a914b
...
bd0a3e091a
Author | SHA1 | Date | |
---|---|---|---|
bd0a3e091a | |||
8bec81c556 | |||
69e049e1e6 | |||
74c0aa11cd | |||
cbee43581e |
@ -2,8 +2,8 @@ package eu.jonahbauer.wizard.client.cli.commands;
|
||||
|
||||
import eu.jonahbauer.wizard.client.cli.Client;
|
||||
import eu.jonahbauer.wizard.client.cli.state.Game;
|
||||
import eu.jonahbauer.wizard.client.cli.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -2,7 +2,6 @@ package eu.jonahbauer.wizard.client.cli.state;
|
||||
|
||||
import eu.jonahbauer.wizard.client.cli.Client;
|
||||
import eu.jonahbauer.wizard.client.cli.commands.GameCommand;
|
||||
import eu.jonahbauer.wizard.client.cli.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.messages.client.InteractionMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.data.PlayerData;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.*;
|
||||
@ -12,6 +11,7 @@ import eu.jonahbauer.wizard.common.messages.server.GameMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
@ -1,24 +0,0 @@
|
||||
package eu.jonahbauer.wizard.client.cli.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public record Pair<F,S>(F first, S second) implements Map.Entry<F, S> {
|
||||
public static <F,S> Pair<F,S> of(F first, S second) {
|
||||
return new Pair<>(first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public F getKey() {
|
||||
return first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S getValue() {
|
||||
return second();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S setValue(S value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package eu.jonahbauer.wizard.client.cli.util;
|
||||
|
||||
|
||||
import eu.jonahbauer.wizard.client.cli.Client;
|
||||
import eu.jonahbauer.wizard.client.cli.state.ClientState;
|
||||
import picocli.CommandLine;
|
||||
|
@ -9,6 +9,7 @@ import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import eu.jonahbauer.wizard.client.libgdx.screens.MainMenuScreen;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.SavedData;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.SoundManager;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.WizardAssetManager;
|
||||
import lombok.Getter;
|
||||
|
||||
@ -19,6 +20,8 @@ public class WizardGame extends Game {
|
||||
|
||||
public SpriteBatch batch;
|
||||
public WizardAssetManager assets;
|
||||
public SoundManager sounds;
|
||||
|
||||
public final SavedData storage = new SavedData();
|
||||
|
||||
private boolean fullscreenToggle;
|
||||
@ -35,6 +38,8 @@ public class WizardGame extends Game {
|
||||
assets.loadShared();
|
||||
assets.finishLoading();
|
||||
|
||||
sounds = new SoundManager(assets);
|
||||
|
||||
// background music
|
||||
Music backgroundMusic = assets.get(WizardAssetManager.MUSIC_BACKGROUND, Music.class);
|
||||
backgroundMusic.setLooping(true);
|
||||
@ -77,6 +82,7 @@ public class WizardGame extends Game {
|
||||
@Override
|
||||
public void dispose () {
|
||||
batch.dispose();
|
||||
sounds.dispose();
|
||||
assets.dispose();
|
||||
client.shutdownNow();
|
||||
var socket = client.getSocket();
|
||||
|
@ -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<T> extends List<T> {
|
||||
@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, "...");
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package eu.jonahbauer.wizard.client.libgdx.listeners;
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.SoundManager;
|
||||
|
||||
public class ButtonClickListener extends ChangeListener {
|
||||
private final SoundManager sounds;
|
||||
|
||||
public ButtonClickListener(SoundManager sounds) {
|
||||
this.sounds = sounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor instanceof Button) {
|
||||
sounds.sfxClick();
|
||||
}
|
||||
}
|
||||
}
|
@ -29,7 +29,6 @@ public class ConnectScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonBack) {
|
||||
game.getClient().execute(Menu.class, Menu::showMenuScreen);
|
||||
sfxClick();
|
||||
} else if (actor == buttonConnect) {
|
||||
try {
|
||||
var uriString = ConnectScreen.this.uriField.getText();
|
||||
@ -39,8 +38,6 @@ public class ConnectScreen extends MenuScreen {
|
||||
} catch (URISyntaxException e) {
|
||||
uriField.setStyle(getTextFieldErrorStyle());
|
||||
}
|
||||
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -31,10 +31,8 @@ public class CreateGameScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonBack) {
|
||||
game.getClient().execute(Lobby.class, Lobby::showListScreen);
|
||||
sfxClick();
|
||||
} else if (actor == buttonContinue) {
|
||||
create();
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -18,7 +18,6 @@ public class ErrorScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonBack) {
|
||||
game.getClient().execute(BaseState.class, BaseState::dismissErrorScreen);
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -22,10 +22,7 @@ import eu.jonahbauer.wizard.client.libgdx.actors.CardsGroup;
|
||||
import eu.jonahbauer.wizard.client.libgdx.actors.PadOfTruth;
|
||||
import eu.jonahbauer.wizard.client.libgdx.state.Game;
|
||||
import eu.jonahbauer.wizard.client.libgdx.state.Session;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.AnimationTimings;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.CardUtil;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.Pair;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.WizardAssetManager;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.*;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import lombok.Getter;
|
||||
@ -421,6 +418,13 @@ public class GameScreen extends WizardScreen {
|
||||
execute(new StartRoundOverlay(this, round));
|
||||
}
|
||||
|
||||
public void deal() {
|
||||
execute(parallel(
|
||||
run(() -> game.sounds.sfxShuffle()),
|
||||
delay(SoundManager.CARD_SHUFFLE_DURATION)
|
||||
));
|
||||
}
|
||||
|
||||
public void startTrick() {
|
||||
clearActivePlayer();
|
||||
execute(() -> cardStack.clearChildren());
|
||||
@ -531,6 +535,8 @@ public class GameScreen extends WizardScreen {
|
||||
cardStack.add(seat, actor);
|
||||
sequence.addAction(delay(actor));
|
||||
sequence.addAction(delay(AnimationTimings.STACK_HOLD));
|
||||
|
||||
game.sounds.sfxPlayCard();
|
||||
}));
|
||||
execute(sequence);
|
||||
}
|
||||
|
@ -31,15 +31,12 @@ public class InstructionScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonBack) {
|
||||
game.getClient().execute(Menu.class, Menu::showMenuScreen);
|
||||
sfxClick();
|
||||
} else if (actor == nextPageButton) {
|
||||
currentPage = MathUtils.clamp(currentPage + 1, 0, MAX_PAGE);
|
||||
showPage(currentPage);
|
||||
sfxClick();
|
||||
} else if (actor == previousPageButton) {
|
||||
currentPage = MathUtils.clamp(currentPage - 1, 0, MAX_PAGE);
|
||||
showPage(currentPage);
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
package eu.jonahbauer.wizard.client.libgdx.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
|
||||
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
|
||||
|
@ -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<SessionData> sessions;
|
||||
private ScrollPane sessionListContainer;
|
||||
|
||||
@ -34,16 +37,14 @@ public class LobbyScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonBack) {
|
||||
game.getClient().execute(Lobby.class, Lobby::disconnect);
|
||||
sfxClick();
|
||||
} else if (actor == buttonJoin) {
|
||||
join();
|
||||
sfxClick();
|
||||
if (rejoin) {
|
||||
game.getClient().execute(Lobby.class, Lobby::showRejoinScreen);
|
||||
} else {
|
||||
join();
|
||||
}
|
||||
} 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 +65,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 +108,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 +199,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;
|
||||
|
||||
|
@ -23,13 +23,10 @@ public class MainMenuScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonPlay) {
|
||||
game.getClient().execute(Menu.class, Menu::showConnectScreen);
|
||||
sfxClick();
|
||||
} else if (actor == buttonQuit) {
|
||||
sfxClick();
|
||||
Gdx.app.exit();
|
||||
} else if (actor == buttonInstruction) {
|
||||
game.getClient().execute(Menu.class, Menu::showInstructionScreen);
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -26,10 +26,8 @@ public class RejoinScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonBack) {
|
||||
game.getClient().execute(Lobby.class, Lobby::showListScreen);
|
||||
sfxClick();
|
||||
} else if (actor == buttonContinue) {
|
||||
rejoin();
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
@ -17,7 +14,7 @@ import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class WaitingScreen extends MenuScreen {
|
||||
public class SessionScreen extends MenuScreen {
|
||||
|
||||
private TextButton buttonLeave;
|
||||
private TextButton buttonReady;
|
||||
@ -34,15 +31,13 @@ public class WaitingScreen extends MenuScreen {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (actor == buttonLeave) {
|
||||
game.getClient().execute(Session.class, Session::leave);
|
||||
sfxClick();
|
||||
} else if (actor == buttonReady) {
|
||||
game.getClient().execute(Session.class, Session::toggleReady);
|
||||
sfxClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public WaitingScreen(WizardGame game) {
|
||||
public SessionScreen(WizardGame game) {
|
||||
super(game);
|
||||
}
|
||||
|
||||
@ -50,19 +45,19 @@ public class WaitingScreen extends MenuScreen {
|
||||
public void show() {
|
||||
super.show();
|
||||
|
||||
buttonLeave = new TextButton(messages.get("menu.waiting.leave"), skin);
|
||||
buttonLeave = new TextButton(messages.get("menu.session.leave"), skin);
|
||||
buttonLeave.addListener(listener);
|
||||
getButtonGroup().addActor(buttonLeave);
|
||||
|
||||
buttonReady = new TextButton(messages.get("menu.waiting.ready"), skin);
|
||||
buttonReady = new TextButton(messages.get("menu.session.ready"), skin);
|
||||
buttonReady.addListener(listener);
|
||||
getButtonGroup().addActor(buttonReady);
|
||||
|
||||
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 +65,8 @@ public class WaitingScreen 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;
|
||||
}
|
||||
};
|
||||
|
||||
@ -121,13 +108,13 @@ public class WaitingScreen extends MenuScreen {
|
||||
infoTable.columnDefaults(0).growX().width(infoTableWidth);
|
||||
infoTable.setSize(infoTableWidth, 400);
|
||||
|
||||
infoTable.add(messages.get("menu.waiting.session_name.label")).row();
|
||||
infoTable.add(messages.get("menu.session.session_name.label")).row();
|
||||
infoTable.add(labelSessionName).row();
|
||||
infoTable.add(messages.get("menu.waiting.session_uuid.label")).row();
|
||||
infoTable.add(messages.get("menu.session.session_uuid.label")).row();
|
||||
infoTable.add(labelSessionUUID).row();
|
||||
infoTable.add(messages.get("menu.waiting.session_configuration.label")).row();
|
||||
infoTable.add(messages.get("menu.session.session_configuration.label")).row();
|
||||
infoTable.add(labelSessionConfiguration).row();
|
||||
infoTable.add(messages.get("menu.waiting.player_name.label")).row();
|
||||
infoTable.add(messages.get("menu.session.player_name.label")).row();
|
||||
infoTable.add(labelPlayerName).row();
|
||||
|
||||
return infoTable;
|
||||
@ -138,7 +125,7 @@ public class WaitingScreen extends MenuScreen {
|
||||
}
|
||||
|
||||
public void setReady(boolean ready) {
|
||||
buttonReady.setText(messages.get(ready ? "menu.waiting.not_ready" : "menu.waiting.ready"));
|
||||
buttonReady.setText(messages.get(ready ? "menu.session.not_ready" : "menu.session.ready"));
|
||||
}
|
||||
|
||||
public void addPlayer(PlayerData player) {
|
@ -2,7 +2,6 @@ package eu.jonahbauer.wizard.client.libgdx.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
@ -16,6 +15,7 @@ import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
import eu.jonahbauer.wizard.client.libgdx.UiskinAtlas;
|
||||
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
|
||||
import eu.jonahbauer.wizard.client.libgdx.listeners.AutoFocusListener;
|
||||
import eu.jonahbauer.wizard.client.libgdx.listeners.ButtonClickListener;
|
||||
import eu.jonahbauer.wizard.client.libgdx.listeners.ButtonKeyListener;
|
||||
import eu.jonahbauer.wizard.client.libgdx.util.WizardAssetManager;
|
||||
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
||||
@ -31,7 +31,6 @@ public abstract class WizardScreen implements Screen {
|
||||
protected Viewport viewport;
|
||||
|
||||
private Image background;
|
||||
private Sound sfxClick;
|
||||
|
||||
protected float offsetX;
|
||||
protected float offsetY;
|
||||
@ -56,11 +55,10 @@ public abstract class WizardScreen implements Screen {
|
||||
stage = new Stage(viewport);
|
||||
stage.addListener(new ButtonKeyListener());
|
||||
stage.addListener(new AutoFocusListener());
|
||||
stage.addListener(new ButtonClickListener(game.sounds));
|
||||
stage.setDebugAll(WizardGame.DEBUG);
|
||||
|
||||
Gdx.input.setInputProcessor(stage);
|
||||
|
||||
sfxClick = assets.get(WizardAssetManager.SFX_CLICK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -110,8 +108,4 @@ public abstract class WizardScreen implements Screen {
|
||||
public void dispose() {
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
protected void sfxClick() {
|
||||
sfxClick.play(0.6f);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public final class AwaitingJoinSession extends Awaiting {
|
||||
));
|
||||
} else {
|
||||
return Optional.of(new Session(
|
||||
new SessionData(session, sessionName, -1, configuration),
|
||||
session, sessionName, configuration,
|
||||
players,
|
||||
player
|
||||
));
|
||||
|
@ -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;
|
||||
@ -118,6 +117,7 @@ public final class Game extends BaseState {
|
||||
case "starting_round" -> {
|
||||
return onStartRound(client);
|
||||
}
|
||||
case "dealing" -> onDealing();
|
||||
case "starting_trick" -> onStartTrick();
|
||||
case "juggling" -> onJuggle();
|
||||
case "finishing_round" -> onFinishingRound();
|
||||
@ -190,6 +190,10 @@ public final class Game extends BaseState {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void onDealing() {
|
||||
if (gameScreen != null) gameScreen.deal();
|
||||
}
|
||||
|
||||
private void onStartTrick() {
|
||||
log.info("Trick {} is starting...", trick + 1);
|
||||
trick ++;
|
||||
@ -433,7 +437,7 @@ public final class Game extends BaseState {
|
||||
|
||||
private Optional<ClientState> returnToSession() {
|
||||
return Optional.of(new Session(
|
||||
new SessionData(session, sessionName, -1, configuration),
|
||||
session, sessionName, configuration,
|
||||
players.entrySet().stream()
|
||||
.map(entry -> new PlayerData(entry.getKey(), entry.getValue(), false))
|
||||
.toList(),
|
||||
|
@ -1,11 +1,10 @@
|
||||
package eu.jonahbauer.wizard.client.libgdx.state;
|
||||
|
||||
import eu.jonahbauer.wizard.client.libgdx.Client;
|
||||
import eu.jonahbauer.wizard.client.libgdx.screens.WaitingScreen;
|
||||
import eu.jonahbauer.wizard.client.libgdx.screens.SessionScreen;
|
||||
import eu.jonahbauer.wizard.common.messages.client.LeaveSessionMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.client.ReadyMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.data.PlayerData;
|
||||
import eu.jonahbauer.wizard.common.messages.data.SessionData;
|
||||
import eu.jonahbauer.wizard.common.messages.server.*;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import lombok.Getter;
|
||||
@ -16,7 +15,7 @@ import java.util.*;
|
||||
@Log4j2
|
||||
@Getter
|
||||
public final class Session extends BaseState {
|
||||
private WaitingScreen sessionScreen;
|
||||
private SessionScreen sessionScreen;
|
||||
|
||||
private final UUID self;
|
||||
|
||||
@ -28,14 +27,14 @@ public final class Session extends BaseState {
|
||||
|
||||
private boolean sending;
|
||||
|
||||
public Session(SessionData session, Collection<PlayerData> players, UUID self) {
|
||||
this(session, players, self, false);
|
||||
public Session(UUID session, String name, Configuration configuration, Collection<PlayerData> players, UUID self) {
|
||||
this(session, name, configuration, players, self, false);
|
||||
}
|
||||
|
||||
public Session(SessionData session, Collection<PlayerData> players, UUID self, boolean dontSwitchScreen) {
|
||||
this.session = session.getUuid();
|
||||
this.sessionName = session.getName();
|
||||
this.configuration = session.getConfiguration();
|
||||
public Session(UUID session, String name, Configuration configuration, Collection<PlayerData> players, UUID self, boolean dontSwitchScreen) {
|
||||
this.session = session;
|
||||
this.sessionName = name;
|
||||
this.configuration = configuration;
|
||||
players.forEach(p -> this.players.put(p.getUuid(), p));
|
||||
this.dontSwitchScreen = dontSwitchScreen;
|
||||
|
||||
@ -122,7 +121,7 @@ public final class Session extends BaseState {
|
||||
}
|
||||
|
||||
public Optional<ClientState> showInfoScreen(Client client) {
|
||||
sessionScreen = new WaitingScreen(client.getGame());
|
||||
sessionScreen = new SessionScreen(client.getGame());
|
||||
client.getGame().setScreen(sessionScreen);
|
||||
sessionScreen.setPlayers(players.values().toArray(new PlayerData[0]));
|
||||
sessionScreen.setReady(players.get(self).isReady());
|
||||
|
@ -0,0 +1,47 @@
|
||||
package eu.jonahbauer.wizard.client.libgdx.util;
|
||||
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
import lombok.Setter;
|
||||
|
||||
public class SoundManager {
|
||||
public static final float CARD_SHUFFLE_DURATION = 4.2f;
|
||||
|
||||
private final WizardAssetManager assets;
|
||||
|
||||
@Setter
|
||||
private float sfxVolume = 1;
|
||||
|
||||
private final Sound click;
|
||||
private final Sound cardPlayed;
|
||||
private final Sound cardShuffle;
|
||||
|
||||
public SoundManager(WizardAssetManager assets) {
|
||||
this.assets = assets;
|
||||
assets.load(WizardAssetManager.SFX_CLICK, Sound.class);
|
||||
assets.load(WizardAssetManager.SFX_CARD_PLAYED, Sound.class);
|
||||
assets.load(WizardAssetManager.SFX_CARD_SHUFFLE, Sound.class);
|
||||
assets.finishLoading();
|
||||
|
||||
this.click = assets.get(WizardAssetManager.SFX_CLICK);
|
||||
this.cardPlayed = assets.get(WizardAssetManager.SFX_CARD_PLAYED);
|
||||
this.cardShuffle = assets.get(WizardAssetManager.SFX_CARD_SHUFFLE);
|
||||
}
|
||||
|
||||
public void sfxClick() {
|
||||
this.click.play(sfxVolume);
|
||||
}
|
||||
|
||||
public void sfxShuffle() {
|
||||
this.cardShuffle.play(sfxVolume);
|
||||
}
|
||||
|
||||
public void sfxPlayCard() {
|
||||
this.cardPlayed.play(sfxVolume);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
assets.unload(WizardAssetManager.SFX_CLICK);
|
||||
assets.unload(WizardAssetManager.SFX_CARD_PLAYED);
|
||||
assets.unload(WizardAssetManager.SFX_CARD_SHUFFLE);
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.assets.AssetManager;
|
||||
import com.badlogic.gdx.assets.loaders.I18NBundleLoader;
|
||||
import com.badlogic.gdx.assets.loaders.SkinLoader;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
@ -20,7 +19,9 @@ public class WizardAssetManager {
|
||||
public static final String ATLAS_SKIN = UiskinAtlas.$PATH;
|
||||
public static final String ATLAS_GAME = GameAtlas.$PATH;
|
||||
|
||||
public static final String SFX_CLICK = "button_click_s.mp3";
|
||||
public static final String SFX_CLICK = "sound/button_click.mp3";
|
||||
public static final String SFX_CARD_PLAYED = "sound/card_played.mp3";
|
||||
public static final String SFX_CARD_SHUFFLE = "sound/card_shuffle.mp3";
|
||||
public static final String MUSIC_BACKGROUND = "background.mp3";
|
||||
|
||||
public static final String CURSOR = "cursor.png";
|
||||
@ -35,7 +36,6 @@ public class WizardAssetManager {
|
||||
manager.load(SKIN, Skin.class, new SkinLoader.SkinParameter(ATLAS_SKIN));
|
||||
|
||||
manager.load(MUSIC_BACKGROUND, Music.class);
|
||||
manager.load(SFX_CLICK, Sound.class);
|
||||
}
|
||||
|
||||
public void loadGame() {
|
||||
|
@ -150,14 +150,14 @@ menu.loading.joining_session=Joining session...
|
||||
menu.loading.joining_lobby=Joining lobby...
|
||||
menu.loading.back=Return To Main Menu
|
||||
|
||||
menu.waiting.ready=Ready
|
||||
menu.waiting.not_ready=Not Ready
|
||||
menu.waiting.leave=Leave
|
||||
menu.session.ready=Ready
|
||||
menu.session.not_ready=Not Ready
|
||||
menu.session.leave=Leave
|
||||
|
||||
menu.waiting.player_name.label=Own Name
|
||||
menu.waiting.session_name.label=Session Name
|
||||
menu.waiting.session_uuid.label=Session UUID
|
||||
menu.waiting.session_configuration.label=Configuration
|
||||
menu.session.player_name.label=Own Name
|
||||
menu.session.session_name.label=Session Name
|
||||
menu.session.session_uuid.label=Session UUID
|
||||
menu.session.session_configuration.label=Configuration
|
||||
|
||||
menu.error.malformed_message=Error: Malformed Message
|
||||
menu.error.unexpected_message=Error: Unexpected Message
|
||||
|
@ -143,14 +143,14 @@ menu.loading.joining_session=Trete Sitzung bei...
|
||||
menu.loading.joining_lobby=Trete Warteraum bei...
|
||||
menu.loading.back=Zurück zum Hauptmenü
|
||||
|
||||
menu.waiting.ready=Bereit
|
||||
menu.waiting.not_ready=Nicht Bereit
|
||||
menu.waiting.leave=Verlassen
|
||||
menu.session.ready=Bereit
|
||||
menu.session.not_ready=Nicht Bereit
|
||||
menu.session.leave=Verlassen
|
||||
|
||||
menu.waiting.player_name.label=Eigener Name
|
||||
menu.waiting.session_name.label=Sitzungsname
|
||||
menu.waiting.session_uuid.label=Sitzungs-ID
|
||||
menu.waiting.session_configuration.label=Spielvariante
|
||||
menu.session.player_name.label=Eigener Name
|
||||
menu.session.session_name.label=Sitzungsname
|
||||
menu.session.session_uuid.label=Sitzungs-ID
|
||||
menu.session.session_configuration.label=Spielvariante
|
||||
|
||||
menu.error.malformed_message=Fehler: Missgebildete Nachricht
|
||||
menu.error.unexpected_message=Fehler: Unerwartete Nachricht
|
||||
|
Binary file not shown.
Binary file not shown.
@ -3,7 +3,7 @@ package eu.jonahbauer.wizard.common.messages.client;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.jonahbauer.wizard.common.messages.ParseException;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.common.util.SerializationUtil;
|
||||
import eu.jonahbauer.wizard.common.messages.util.SerializationUtil;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package eu.jonahbauer.wizard.common.messages.observer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.jonahbauer.wizard.common.messages.ParseException;
|
||||
import eu.jonahbauer.wizard.common.util.SerializationUtil;
|
||||
import eu.jonahbauer.wizard.common.messages.util.SerializationUtil;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
|
@ -2,7 +2,7 @@ package eu.jonahbauer.wizard.common.messages.player;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.jonahbauer.wizard.common.messages.ParseException;
|
||||
import eu.jonahbauer.wizard.common.util.SerializationUtil;
|
||||
import eu.jonahbauer.wizard.common.messages.util.SerializationUtil;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
|
@ -3,7 +3,7 @@ package eu.jonahbauer.wizard.common.messages.server;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.jonahbauer.wizard.common.messages.ParseException;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.ObserverMessage;
|
||||
import eu.jonahbauer.wizard.common.util.SerializationUtil;
|
||||
import eu.jonahbauer.wizard.common.messages.util.SerializationUtil;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package eu.jonahbauer.wizard.common.util;
|
||||
package eu.jonahbauer.wizard.common.messages.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
@ -10,10 +10,10 @@ import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
||||
import eu.jonahbauer.wizard.common.messages.ParseException;
|
||||
import eu.jonahbauer.wizard.common.util.StringUtil;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Locale;
|
||||
|
||||
@UtilityClass
|
||||
public class SerializationUtil {
|
||||
@ -61,7 +61,7 @@ public class SerializationUtil {
|
||||
if (Modifier.isFinal(modifiers) || subclass.isSealed() && !Modifier.isAbstract(modifiers)) {
|
||||
var name = subclass.getSimpleName();
|
||||
if (name.endsWith(suffix)) name = name.substring(0, name.length() - suffix.length());
|
||||
name = name.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase(Locale.ROOT);
|
||||
name = StringUtil.toSnakeCase(name);
|
||||
|
||||
objectMapper.registerSubtypes(new NamedType(subclass, name));
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package eu.jonahbauer.wizard.core.util;
|
||||
package eu.jonahbauer.wizard.common.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -1,11 +1,11 @@
|
||||
package eu.jonahbauer.wizard.core.util;
|
||||
package eu.jonahbauer.wizard.common.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@UtilityClass
|
||||
public class Util {
|
||||
public class StringUtil {
|
||||
public static String toSnakeCase(String str) {
|
||||
return str.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase(Locale.ROOT);
|
||||
}
|
23
wizard-common/src/main/java/module-info.java
Normal file
23
wizard-common/src/main/java/module-info.java
Normal file
@ -0,0 +1,23 @@
|
||||
module eu.jonahbauer.wizard.common {
|
||||
exports eu.jonahbauer.wizard.common.machine;
|
||||
exports eu.jonahbauer.wizard.common.messages;
|
||||
exports eu.jonahbauer.wizard.common.messages.client;
|
||||
exports eu.jonahbauer.wizard.common.messages.data;
|
||||
exports eu.jonahbauer.wizard.common.messages.observer;
|
||||
exports eu.jonahbauer.wizard.common.messages.player;
|
||||
exports eu.jonahbauer.wizard.common.messages.server;
|
||||
exports eu.jonahbauer.wizard.common.model;
|
||||
exports eu.jonahbauer.wizard.common.util;
|
||||
|
||||
opens eu.jonahbauer.wizard.common.messages.client to com.fasterxml.jackson.databind;
|
||||
opens eu.jonahbauer.wizard.common.messages.data to com.fasterxml.jackson.databind;
|
||||
opens eu.jonahbauer.wizard.common.messages.observer to com.fasterxml.jackson.databind;
|
||||
opens eu.jonahbauer.wizard.common.messages.player to com.fasterxml.jackson.databind;
|
||||
opens eu.jonahbauer.wizard.common.messages.server to com.fasterxml.jackson.databind;
|
||||
|
||||
requires com.fasterxml.jackson.databind;
|
||||
requires com.fasterxml.jackson.module.paramnames;
|
||||
|
||||
requires static lombok;
|
||||
requires static org.jetbrains.annotations;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
package eu.jonahbauer.wizard.core;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.player.PickTrumpMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayCardMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PredictMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.messages.Observer;
|
||||
import eu.jonahbauer.wizard.core.model.GameConfiguration;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CLI {
|
||||
public static void main(String[] args) {
|
||||
GameConfiguration config = Configurations.DEFAULT;
|
||||
Observer observer = (player, msg) -> System.out.println(msg);
|
||||
Game game = new Game(config, observer);
|
||||
var players = List.of(
|
||||
UUID.randomUUID(),
|
||||
UUID.randomUUID(),
|
||||
UUID.randomUUID(),
|
||||
UUID.randomUUID()
|
||||
);
|
||||
|
||||
game.start(players);
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
Pattern pattern = Pattern.compile("(\\d) ([a-z]+) (.*)");
|
||||
while (scanner.hasNextLine()) {
|
||||
try {
|
||||
Matcher matcher = pattern.matcher(scanner.nextLine());
|
||||
if (!matcher.find()) {
|
||||
System.err.println("Format is \"(\\d) ([a-z]+) (.*)\"");
|
||||
continue;
|
||||
}
|
||||
String player = matcher.group(1);
|
||||
String command = matcher.group(2);
|
||||
String param = matcher.group(3);
|
||||
|
||||
int id = Integer.parseInt(player);
|
||||
|
||||
if (id > players.size()) {
|
||||
System.err.println("ID must be between 0 and " + (players.size() - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
case "predict" -> {
|
||||
int prediction = Integer.parseInt(param);
|
||||
game.onMessage(players.get(id), new PredictMessage(prediction));
|
||||
}
|
||||
case "play" -> {
|
||||
Card card = Card.valueOf(param);
|
||||
game.onMessage(players.get(id), new PlayCardMessage(card));
|
||||
}
|
||||
case "trump" -> {
|
||||
Card.Suit suit = Card.Suit.valueOf(param);
|
||||
game.onMessage(players.get(id), new PickTrumpMessage(suit));
|
||||
}
|
||||
default -> System.err.println("Unknown command: " + command);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,22 @@
|
||||
package eu.jonahbauer.wizard.core.machine;
|
||||
package eu.jonahbauer.wizard.core;
|
||||
|
||||
import eu.jonahbauer.wizard.common.machine.TimeoutContext;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.ObserverMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.StateMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.core.machine.states.TransientState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Created;
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Error;
|
||||
import eu.jonahbauer.wizard.core.messages.Observer;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.TransientState;
|
||||
import eu.jonahbauer.wizard.core.states.game.Created;
|
||||
import eu.jonahbauer.wizard.core.states.game.Error;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.core.model.GameConfiguration;
|
||||
import eu.jonahbauer.wizard.core.util.Util;
|
||||
import eu.jonahbauer.wizard.common.util.StringUtil;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.Blocking;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
@ -30,20 +34,25 @@ public final class Game extends TimeoutContext<GameState, Game> {
|
||||
|
||||
private final CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
public Game(GameConfiguration config, Observer observer) {
|
||||
private Game(Random random, Configuration config, long timeout, long syncTimeout, Observer observer) {
|
||||
super(new Created());
|
||||
this.random = new Random();
|
||||
this.config = config;
|
||||
this.random = random;
|
||||
this.config = Configurations.get(config).withTimeout(timeout).withSyncTimeout(syncTimeout);
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
public Game(long seed, GameConfiguration config, Observer observer) {
|
||||
super(new Created());
|
||||
this.random = new Random(seed);
|
||||
this.config = config;
|
||||
this.observer = observer;
|
||||
public Game(Configuration config, long timeout, long syncTimeout, Observer observer) {
|
||||
this(new Random(), config, timeout, syncTimeout, observer);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public Game(long seed, Configuration config, long timeout, long syncTimeout, Observer observer) {
|
||||
this(new Random(seed), config, timeout, syncTimeout, observer);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@VisibleForTesting
|
||||
@SuppressWarnings("ClassEscapesDefinedScope")
|
||||
public void resume(GameState state) {
|
||||
transition(new Created(), state);
|
||||
}
|
||||
@ -56,10 +65,17 @@ public final class Game extends TimeoutContext<GameState, Game> {
|
||||
execute(s -> s.onMessage(this, player, message));
|
||||
}
|
||||
|
||||
public void onMessage(UUID player, PlayerMessage message, Runnable preHandleMessage) {
|
||||
execute(s -> {
|
||||
preHandleMessage.run();
|
||||
return s.onMessage(this, player, message);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTransition(GameState from, GameState to) {
|
||||
if (!(to instanceof TransientState)) {
|
||||
notify(new StateMessage(to != null ? Util.toSnakeCase(to.getClass().getSimpleName()) : "null"));
|
||||
notify(new StateMessage(to != null ? StringUtil.toSnakeCase(to.getClass().getSimpleName()) : "null"));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package eu.jonahbauer.wizard.core.messages;
|
||||
package eu.jonahbauer.wizard.core;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.ObserverMessage;
|
||||
|
@ -1,4 +0,0 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states;
|
||||
|
||||
public interface TransientState {
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.game;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.round.StartingRound;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.PLAYERS;
|
||||
|
||||
public final class Starting extends GameState {
|
||||
|
||||
public Starting(GameData data) {
|
||||
super(data.require(PLAYERS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<GameState> onEnter(Game game) {
|
||||
return transition(new StartingRound(getData()));
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states;
|
||||
package eu.jonahbauer.wizard.core.states;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
@ -1,10 +1,9 @@
|
||||
package eu.jonahbauer.wizard.core.machine;
|
||||
package eu.jonahbauer.wizard.core.states;
|
||||
|
||||
import eu.jonahbauer.wizard.common.machine.TimeoutState;
|
||||
import eu.jonahbauer.wizard.common.messages.player.ContinueMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.SyncState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
@ -13,8 +12,8 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.CURRENT_PLAYER;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.PLAYERS;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.CURRENT_PLAYER;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.PLAYERS;
|
||||
|
||||
@Unmodifiable
|
||||
public abstract class GameState implements TimeoutState<GameState, Game> {
|
@ -1,4 +1,4 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states;
|
||||
package eu.jonahbauer.wizard.core.states;
|
||||
|
||||
public class InvalidDataException extends RuntimeException {
|
||||
public InvalidDataException(String message) {
|
@ -1,11 +1,10 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states;
|
||||
package eu.jonahbauer.wizard.core.states;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.ContinueMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
@ -14,7 +13,7 @@ import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.SYNC;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.PLAYERS;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.PLAYERS;
|
||||
|
||||
public final class SyncState extends GameState implements TransientState {
|
||||
private final transient Set<UUID> ready = new HashSet<>();
|
@ -0,0 +1,4 @@
|
||||
package eu.jonahbauer.wizard.core.states;
|
||||
|
||||
public interface TransientState {
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.game;
|
||||
package eu.jonahbauer.wizard.core.states.game;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.game;
|
||||
package eu.jonahbauer.wizard.core.states.game;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
@ -1,8 +1,8 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.game;
|
||||
package eu.jonahbauer.wizard.core.states.game;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
|
||||
import java.util.Optional;
|
||||
|
@ -1,13 +1,13 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.game;
|
||||
package eu.jonahbauer.wizard.core.states.game;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.ScoreMessage;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class Finishing extends GameState {
|
||||
|
@ -0,0 +1,22 @@
|
||||
package eu.jonahbauer.wizard.core.states.game;
|
||||
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.round.StartingRound;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.PLAYERS;
|
||||
|
||||
public final class Starting extends GameState {
|
||||
|
||||
public Starting(GameData data) {
|
||||
super(data.require(PLAYERS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<GameState> onEnter(Game game) {
|
||||
return transition(new StartingRound(getData()));
|
||||
}
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.PredictionMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PredictMessage;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.InvalidDataException;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.InvalidDataException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -16,7 +16,7 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.CHANGE_PREDICTION;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class ChangingPrediction extends RoundState {
|
||||
private transient final int oldPrediction;
|
@ -1,15 +1,15 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.HandMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.model.deck.Deck;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class Dealing extends RoundState {
|
||||
|
@ -1,15 +1,15 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TrumpMessage;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.model.card.GameCards;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class DeterminingTrump extends RoundState {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.HandMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
|
||||
@ -7,17 +7,17 @@ import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PickTrumpMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.TransientState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.TransientState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.PICK_TRUMP;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.TRUMP_CARD;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.TRUMP_CARD;
|
||||
|
||||
public final class DeterminingTrumpUserInput extends RoundState implements TransientState {
|
||||
private final transient UUID player;
|
@ -1,9 +1,9 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Finishing;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.game.Finishing;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.ScoreMessage;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -11,7 +11,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class FinishingRound extends RoundState {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.trick.StartingTrick;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.trick.StartingTrick;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.PredictionMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
@ -16,7 +16,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.MAKE_PREDICTION;
|
||||
|
||||
@Getter
|
@ -1,11 +1,11 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public abstract class RoundState extends GameState {
|
||||
public static GameData requirements(GameData data) {
|
@ -1,8 +1,8 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
|
||||
import java.util.Optional;
|
||||
|
@ -1,19 +1,19 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.trick;
|
||||
package eu.jonahbauer.wizard.core.states.trick;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.InvalidDataException;
|
||||
import eu.jonahbauer.wizard.core.machine.states.round.ChangingPrediction;
|
||||
import eu.jonahbauer.wizard.core.machine.states.round.FinishingRound;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.InvalidDataException;
|
||||
import eu.jonahbauer.wizard.core.states.round.ChangingPrediction;
|
||||
import eu.jonahbauer.wizard.core.states.round.FinishingRound;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TrickMessage;
|
||||
import eu.jonahbauer.wizard.core.model.card.*;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class FinishingTrick extends TrickState {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.trick;
|
||||
package eu.jonahbauer.wizard.core.states.trick;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.HandMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
|
||||
@ -6,15 +6,15 @@ import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.JuggleMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.*;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public final class Juggling extends TrickState {
|
||||
private final transient Map<UUID, Card> juggledCards = new ConcurrentHashMap<>();
|
@ -1,22 +1,22 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.trick;
|
||||
package eu.jonahbauer.wizard.core.states.trick;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.InvalidDataException;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.InvalidDataException;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.CardMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayCardMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.core.model.card.GameCards;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.PLAY_CARD;
|
||||
|
||||
public final class PlayingCard extends TrickState {
|
@ -1,8 +1,8 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.trick;
|
||||
package eu.jonahbauer.wizard.core.states.trick;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
|
||||
import java.util.Optional;
|
||||
|
@ -1,9 +1,9 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.trick;
|
||||
package eu.jonahbauer.wizard.core.states.trick;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.round.RoundState;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.round.RoundState;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
|
||||
public abstract class TrickState extends RoundState {
|
||||
public static GameData requirements(GameData data) {
|
8
wizard-core/src/main/java/module-info.java
Normal file
8
wizard-core/src/main/java/module-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
module eu.jonahbauer.wizard.core {
|
||||
exports eu.jonahbauer.wizard.core;
|
||||
|
||||
requires eu.jonahbauer.wizard.common;
|
||||
|
||||
requires static lombok;
|
||||
requires static org.jetbrains.annotations;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.machine;
|
||||
package eu.jonahbauer.wizard.core;
|
||||
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.RepetitionInfo;
|
||||
|
||||
@ -13,7 +14,7 @@ public class GameTest {
|
||||
public void runDefault(RepetitionInfo repetitionInfo) throws InterruptedException, ExecutionException {
|
||||
Game game = new Game(
|
||||
repetitionInfo.getCurrentRepetition(),
|
||||
Configurations.DEFAULT.withTimeout(0).withSyncTimeout(0),
|
||||
Configuration.DEFAULT, 0, 0,
|
||||
(player, msg) -> System.out.println(msg)
|
||||
);
|
||||
var players = List.of(
|
||||
@ -31,7 +32,7 @@ public class GameTest {
|
||||
public void runAnniversary2016(RepetitionInfo repetitionInfo) throws InterruptedException, ExecutionException {
|
||||
Game game = new Game(
|
||||
repetitionInfo.getCurrentRepetition(),
|
||||
Configurations.ANNIVERSARY_2016.withTimeout(0).withSyncTimeout(0),
|
||||
Configuration.ANNIVERSARY_2016, 0, 0,
|
||||
(player, msg) -> System.out.println(msg)
|
||||
);
|
||||
var players = List.of(
|
||||
@ -49,7 +50,7 @@ public class GameTest {
|
||||
public void runAnniversary2021(RepetitionInfo repetitionInfo) throws InterruptedException, ExecutionException {
|
||||
Game game = new Game(
|
||||
repetitionInfo.getCurrentRepetition(),
|
||||
Configurations.ANNIVERSARY_2021.withTimeout(0).withSyncTimeout(0),
|
||||
Configuration.ANNIVERSARY_2021, 0, 0,
|
||||
(player, msg) -> System.out.println(msg)
|
||||
);
|
||||
var players = List.of(
|
@ -1,6 +1,6 @@
|
||||
package eu.jonahbauer.wizard.core.machine;
|
||||
package eu.jonahbauer.wizard.core;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Finished;
|
||||
import eu.jonahbauer.wizard.core.states.game.Finished;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.stubbing.Answer;
|
@ -1,11 +1,11 @@
|
||||
package eu.jonahbauer.wizard.core.machine;
|
||||
package eu.jonahbauer.wizard.core;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.ObserverMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.*;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.messages.Observer;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.GameState;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
@ -1,7 +1,7 @@
|
||||
package eu.jonahbauer.wizard.core.model.card;
|
||||
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states;
|
||||
package eu.jonahbauer.wizard.core.states;
|
||||
|
||||
import eu.jonahbauer.wizard.core.machine.GameState;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
@ -1,17 +1,16 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.HandMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.StateMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.TrumpMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.SyncState;
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Finished;
|
||||
import eu.jonahbauer.wizard.core.model.GameConfiguration;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.SyncState;
|
||||
import eu.jonahbauer.wizard.core.states.game.Finished;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
@ -20,9 +19,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.GameTestUtils.doFinish;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.TypedValue.entry;
|
||||
import static eu.jonahbauer.wizard.core.GameTestUtils.doFinish;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.TypedValue.entry;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ -36,8 +35,8 @@ public class DeterminingTrumpTest {
|
||||
|
||||
@SneakyThrows
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private Game performTest(GameConfiguration configuration, int round, Map<UUID, List<Card>> hands, Card trumpCard, MessageQueue queue) {
|
||||
Game game = spy(new Game(configuration, queue));
|
||||
private Game performTest(Configuration configuration, int round, Map<UUID, List<Card>> hands, Card trumpCard, MessageQueue queue) {
|
||||
Game game = spy(new Game(configuration, 10 * 60 * 1000, 10 * 60 * 1000, queue));
|
||||
doFinish().when(game).transition(argThat(argument -> argument instanceof SyncState && argument.getData().has(TRUMP_SUIT)));
|
||||
queue.setGame(game);
|
||||
|
||||
@ -70,7 +69,7 @@ public class DeterminingTrumpTest {
|
||||
// play cards in given order
|
||||
MessageQueue queue = new MessageQueue();
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.YELLOW_1, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 0, hands, Card.YELLOW_1, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -95,7 +94,7 @@ public class DeterminingTrumpTest {
|
||||
MessageQueue queue = new MessageQueue()
|
||||
.sync(players);
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.GREEN_JESTER, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 0, hands, Card.GREEN_JESTER, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -121,7 +120,7 @@ public class DeterminingTrumpTest {
|
||||
.sync(players)
|
||||
.addPickTrump(players[0], Card.Suit.GREEN);
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.BLUE_WIZARD, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 0, hands, Card.BLUE_WIZARD, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -149,7 +148,7 @@ public class DeterminingTrumpTest {
|
||||
.sync(players)
|
||||
.addPickTrump(players[3], Card.Suit.YELLOW);
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.GREEN_1, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 0, hands, Card.GREEN_1, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
@ -1,17 +1,16 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.PredictionMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.StateMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameTestUtils;
|
||||
import eu.jonahbauer.wizard.core.machine.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Finished;
|
||||
import eu.jonahbauer.wizard.core.machine.states.trick.StartingTrick;
|
||||
import eu.jonahbauer.wizard.core.model.GameConfiguration;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.GameTestUtils;
|
||||
import eu.jonahbauer.wizard.core.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.game.Finished;
|
||||
import eu.jonahbauer.wizard.core.states.trick.StartingTrick;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
@ -21,9 +20,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.GameTestUtils.doFinish;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.TypedValue.entry;
|
||||
import static eu.jonahbauer.wizard.core.GameTestUtils.doFinish;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.TypedValue.entry;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ -37,7 +36,7 @@ public class PredictingTest {
|
||||
|
||||
@SneakyThrows
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private Game performTest(GameConfiguration configuration, int round, MessageQueue queue) {
|
||||
private Game performTest(Configuration configuration, int round, MessageQueue queue) {
|
||||
Map<UUID, List<Card>> hands = Map.of(
|
||||
players[0], Collections.nCopies(round + 1, Card.HIDDEN),
|
||||
players[1], Collections.nCopies(round + 1, Card.HIDDEN),
|
||||
@ -45,7 +44,7 @@ public class PredictingTest {
|
||||
players[3], Collections.nCopies(round + 1, Card.HIDDEN)
|
||||
);
|
||||
|
||||
Game game = spy(new Game(configuration, queue));
|
||||
Game game = spy(new Game(configuration, 10 * 60 * 1000, 10 * 60 * 1000, queue));
|
||||
doFinish().when(game).transition(any(StartingTrick.class));
|
||||
queue.setGame(game);
|
||||
|
||||
@ -77,7 +76,7 @@ public class PredictingTest {
|
||||
.addPrediction(players[2], 3)
|
||||
.addPrediction(players[3], 0);
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 3, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 3, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -119,7 +118,7 @@ public class PredictingTest {
|
||||
.addPrediction(players[3], 0)
|
||||
.end();
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 3, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 3, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -153,7 +152,7 @@ public class PredictingTest {
|
||||
.addPrediction(players[3], 0)
|
||||
.end();
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021_PM1, 3, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021_PM1, 3, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
@ -1,13 +1,12 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.round;
|
||||
package eu.jonahbauer.wizard.core.states.round;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.*;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.game.Finished;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.core.model.GameConfiguration;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.game.Finished;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
@ -17,9 +16,9 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.GameTestUtils.finish;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.TypedValue.entry;
|
||||
import static eu.jonahbauer.wizard.core.GameTestUtils.finish;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.TypedValue.entry;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ -32,8 +31,8 @@ public class RoundTest {
|
||||
};
|
||||
|
||||
@SneakyThrows
|
||||
private Game performTest(long seed, GameConfiguration configuration, int round, MessageQueue queue) {
|
||||
Game game = spy(new Game(seed, configuration, queue));
|
||||
private Game performTest(long seed, Configuration configuration, int round, MessageQueue queue) {
|
||||
Game game = spy(new Game(seed, configuration, 10 * 60 * 1000, 10 * 60 * 1000, queue));
|
||||
doCallRealMethod().doAnswer(finish()).when(game).transition(any(StartingRound.class));
|
||||
queue.setGame(game);
|
||||
|
||||
@ -106,7 +105,7 @@ public class RoundTest {
|
||||
.addCard(players[2], Card.BLUE_6);
|
||||
|
||||
int round = 6;
|
||||
Game game = performTest(0L, Configurations.DEFAULT, round, queue);
|
||||
Game game = performTest(0L, Configuration.DEFAULT, round, queue);
|
||||
game.await();
|
||||
|
||||
InOrder order = inOrder(game);
|
||||
@ -232,7 +231,7 @@ public class RoundTest {
|
||||
.end();
|
||||
|
||||
int round = 6;
|
||||
Game game = performTest(227L, Configurations.ANNIVERSARY_2021_PM1, round, queue);
|
||||
Game game = performTest(227L, Configuration.ANNIVERSARY_2021_PM1, round, queue);
|
||||
game.await();
|
||||
|
||||
InOrder order = inOrder(game);
|
@ -1,14 +1,13 @@
|
||||
package eu.jonahbauer.wizard.core.machine.states.trick;
|
||||
package eu.jonahbauer.wizard.core.states.trick;
|
||||
|
||||
import eu.jonahbauer.wizard.common.messages.observer.*;
|
||||
import eu.jonahbauer.wizard.common.model.Card;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.machine.GameTestUtils;
|
||||
import eu.jonahbauer.wizard.core.machine.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.machine.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.machine.states.round.FinishingRound;
|
||||
import eu.jonahbauer.wizard.core.model.GameConfiguration;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.GameTestUtils;
|
||||
import eu.jonahbauer.wizard.core.MessageQueue;
|
||||
import eu.jonahbauer.wizard.core.states.GameData;
|
||||
import eu.jonahbauer.wizard.core.states.round.FinishingRound;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
@ -17,10 +16,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static eu.jonahbauer.wizard.core.machine.GameTestUtils.doFinish;
|
||||
import static eu.jonahbauer.wizard.core.machine.GameTestUtils.finish;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.machine.states.GameData.TypedValue.entry;
|
||||
import static eu.jonahbauer.wizard.core.GameTestUtils.doFinish;
|
||||
import static eu.jonahbauer.wizard.core.GameTestUtils.finish;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.*;
|
||||
import static eu.jonahbauer.wizard.core.states.GameData.TypedValue.entry;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ -35,8 +34,8 @@ public class TrickTest {
|
||||
|
||||
@SneakyThrows
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private Game performTest(GameConfiguration configuration, int round, int trick, Map<UUID, List<Card>> hands, Card.Suit trump, MessageQueue queue) {
|
||||
Game game = spy(new Game(configuration, queue));
|
||||
private Game performTest(Configuration configuration, int round, int trick, Map<UUID, List<Card>> hands, Card.Suit trump, MessageQueue queue) {
|
||||
Game game = spy(new Game(configuration, 10 * 60 * 1000, 10 * 60 * 1000, queue));
|
||||
doCallRealMethod().doAnswer(finish()).when(game).transition(any(StartingTrick.class));
|
||||
doFinish().when(game).transition(any(FinishingRound.class));
|
||||
queue.setGame(game);
|
||||
@ -75,7 +74,7 @@ public class TrickTest {
|
||||
.sync(players)
|
||||
.addCards(List.of(players), hands, 0);
|
||||
|
||||
Game game = performTest(Configurations.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
Game game = performTest(Configuration.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -116,7 +115,7 @@ public class TrickTest {
|
||||
.addCard(players[3], Card.BLUE_1)
|
||||
.end();
|
||||
|
||||
Game game = performTest(Configurations.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
Game game = performTest(Configuration.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -159,7 +158,7 @@ public class TrickTest {
|
||||
.addCard(players[3], Card.BLUE_1)
|
||||
.addChangePrediction(players[2], 1);
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, 0, hands, Card.Suit.GREEN, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 0, 0, hands, Card.Suit.GREEN, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -203,7 +202,7 @@ public class TrickTest {
|
||||
.addJuggle(players[3], Card.BLUE_1)
|
||||
.end();
|
||||
|
||||
Game game = performTest(Configurations.ANNIVERSARY_2021, 1, 0, hands, Card.Suit.YELLOW, queue);
|
||||
Game game = performTest(Configuration.ANNIVERSARY_2021, 1, 0, hands, Card.Suit.YELLOW, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -248,7 +247,7 @@ public class TrickTest {
|
||||
.addCard(players[2], Card.GREEN_1)
|
||||
.addCard(players[3], Card.BLUE_1);
|
||||
|
||||
Game game = performTest(Configurations.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
Game game = performTest(Configuration.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
||||
@ -290,7 +289,7 @@ public class TrickTest {
|
||||
.addCard(players[2], Card.GREEN_WIZARD)
|
||||
.addCard(players[3], Card.BLUE_1);
|
||||
|
||||
Game game = performTest(Configurations.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
Game game = performTest(Configuration.DEFAULT, 0, 0, hands, Card.Suit.BLUE, queue);
|
||||
|
||||
// validate messages
|
||||
InOrder order = inOrder(game);
|
@ -4,14 +4,22 @@ import eu.jonahbauer.wizard.common.messages.server.*;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.server.debug.DebugSession;
|
||||
import eu.jonahbauer.wizard.server.machine.Player;
|
||||
import eu.jonahbauer.wizard.server.management.LobbyMBean;
|
||||
import eu.jonahbauer.wizard.server.management.SessionMBean;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.StandardMBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class Lobby {
|
||||
@Log4j2
|
||||
public class Lobby implements LobbyMBean {
|
||||
@Language("RegExp")
|
||||
private static final String SESSION_NAME_PATTERN = "[a-zA-Z0-9_' ]{1,20}";
|
||||
private static final Lobby INSTANCE = new Lobby();
|
||||
@ -19,12 +27,17 @@ public class Lobby {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private final MBeanServer mBeanServer;
|
||||
|
||||
private final Map<UUID, Session> sessions = new ConcurrentHashMap<>();
|
||||
private final List<Player> players = new ArrayList<>();
|
||||
// read lock is required whenever players are read or sessions are modified, write lock is required when players are modified
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
private Lobby() {}
|
||||
private Lobby() {
|
||||
mBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
registerLobbyMBean();
|
||||
}
|
||||
|
||||
public Session createSession(@NotNull String name, long timeout, @NotNull Configuration configuration) {
|
||||
if (!name.matches(SESSION_NAME_PATTERN)) {
|
||||
@ -42,6 +55,9 @@ public class Lobby {
|
||||
session = new Session(UUID.randomUUID(), name, timeout, configuration);
|
||||
} while (sessions.putIfAbsent(session.getUuid(), session) != null);
|
||||
|
||||
log.info("Created session {}.", session.getUuid());
|
||||
registerSessionMBean(session);
|
||||
|
||||
notifyPlayers(new SessionCreatedMessage(session.toData()));
|
||||
|
||||
return session;
|
||||
@ -58,6 +74,9 @@ public class Lobby {
|
||||
session = new DebugSession(UUID.randomUUID(), name, timeout, configuration);
|
||||
} while (sessions.putIfAbsent(session.getUuid(), session) != null);
|
||||
|
||||
log.info("Created debug session {}.", session.getUuid());
|
||||
registerSessionMBean(session);
|
||||
|
||||
notifyPlayers(new SessionCreatedMessage(session.toData()));
|
||||
|
||||
return session;
|
||||
@ -73,8 +92,11 @@ public class Lobby {
|
||||
public void removeSession(UUID uuid) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
sessions.remove(uuid);
|
||||
notifyPlayers(new SessionRemovedMessage(uuid));
|
||||
if (sessions.remove(uuid) != null) {
|
||||
log.info("Removed session {}.", uuid);
|
||||
unregisterSessionMBean(uuid);
|
||||
notifyPlayers(new SessionRemovedMessage(uuid));
|
||||
}
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
@ -117,4 +139,53 @@ public class Lobby {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//<editor-fold desc="JMX" defaultstate="collapsed">
|
||||
private void registerLobbyMBean() {
|
||||
try {
|
||||
var name = new ObjectName("eu.jonahbauer.wizard.server:type=Lobby");
|
||||
mBeanServer.registerMBean(new StandardMBean(this, LobbyMBean.class), name);
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not register LobbyMBean.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerSessionMBean(@NotNull Session session) {
|
||||
try {
|
||||
var name = new ObjectName("eu.jonahbauer.wizard.server:type=Session,name=" + session.getUuid());
|
||||
mBeanServer.registerMBean(new StandardMBean(session, SessionMBean.class), name);
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not register SessionMBean for session {}.", session.getUuid(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterSessionMBean(@NotNull UUID uuid) {
|
||||
try {
|
||||
var name = new ObjectName("eu.jonahbauer.wizard.server:type=Session,name=" + uuid);
|
||||
mBeanServer.unregisterMBean(name);
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not unregister SessionMBean for session {}.", uuid, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
return players.size();
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalPlayerCount() {
|
||||
return sessions.values().stream().mapToInt(Session::getPlayerCount).sum() + getPlayerCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSessionCount() {
|
||||
return sessions.size();
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package eu.jonahbauer.wizard.server;
|
||||
|
||||
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.ObserverMessage;
|
||||
@ -9,11 +8,11 @@ import eu.jonahbauer.wizard.common.messages.player.ContinueMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
||||
import eu.jonahbauer.wizard.common.messages.server.*;
|
||||
import eu.jonahbauer.wizard.common.model.Configuration;
|
||||
import eu.jonahbauer.wizard.core.machine.Game;
|
||||
import eu.jonahbauer.wizard.core.messages.Observer;
|
||||
import eu.jonahbauer.wizard.core.model.Configurations;
|
||||
import eu.jonahbauer.wizard.core.util.Pair;
|
||||
import eu.jonahbauer.wizard.core.Game;
|
||||
import eu.jonahbauer.wizard.core.Observer;
|
||||
import eu.jonahbauer.wizard.common.util.Pair;
|
||||
import eu.jonahbauer.wizard.server.machine.Player;
|
||||
import eu.jonahbauer.wizard.server.management.SessionMBean;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -29,7 +28,7 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
@Getter
|
||||
@Log4j2
|
||||
@EqualsAndHashCode(of = "uuid")
|
||||
public class Session implements Observer {
|
||||
public class Session implements Observer, SessionMBean {
|
||||
@Language("RegExp")
|
||||
private static final String PLAYER_NAME_PATTERN = "[a-zA-Z0-9_' ]{1,20}";
|
||||
protected static final int MIN_PLAYERS = 3;
|
||||
@ -54,6 +53,11 @@ public class Session implements Observer {
|
||||
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
|
||||
@ -64,7 +68,7 @@ public class Session implements Observer {
|
||||
* @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.");
|
||||
@ -81,7 +85,7 @@ public class Session implements Observer {
|
||||
sessionPlayer.setPlayer(player);
|
||||
|
||||
notifyJoined(sessionPlayer.toData());
|
||||
Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData()));
|
||||
notifyLobby();
|
||||
|
||||
return sessionPlayer.getUuid();
|
||||
}
|
||||
@ -116,13 +120,13 @@ public class Session implements Observer {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -140,7 +144,7 @@ public class Session implements Observer {
|
||||
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.");
|
||||
}
|
||||
|
||||
@ -165,15 +169,11 @@ public class Session implements Observer {
|
||||
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 {
|
||||
game.execute(s -> {
|
||||
// start buffering while game is locked
|
||||
player.buffer();
|
||||
return s.onMessage(game, uuid, message);
|
||||
});
|
||||
game.onMessage(uuid, message, player::buffer);
|
||||
player.send(new AckMessage());
|
||||
} catch (IllegalStateException e) {
|
||||
throw new NackException(NackMessage.ILLEGAL_STATE, e.getMessage());
|
||||
@ -183,10 +183,11 @@ public class Session implements Observer {
|
||||
}
|
||||
}
|
||||
|
||||
protected void startGame() {
|
||||
protected synchronized void startGame() {
|
||||
notifyPlayers(new StartingGameMessage());
|
||||
messages.add(Pair.of(null, new StartingGameMessage()));
|
||||
game = new Game(Configurations.get(configuration).withTimeout(timeout), this);
|
||||
game = new Game(configuration, timeout, 10 * 60 * 1000, this);
|
||||
notifyLobby();
|
||||
game.start(List.copyOf(players.keySet()));
|
||||
CompletableFuture.runAsync(() -> {
|
||||
while (true) {
|
||||
@ -200,20 +201,23 @@ public class Session implements Observer {
|
||||
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())) {
|
||||
@ -229,14 +233,14 @@ public class Session implements Observer {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -271,6 +275,30 @@ public class Session implements Observer {
|
||||
}
|
||||
}
|
||||
|
||||
protected void notifyLobby() {
|
||||
Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData()));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
for (var sessionPlayer : getPlayers().values()) {
|
||||
var player = sessionPlayer.getPlayer();
|
||||
if (player != null) {
|
||||
player.disconnect("Session was forcibly closed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<editor-fold desc="JMX" defaulstate="collapsed">
|
||||
public boolean isDebug() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getPlayerCount() {
|
||||
return players.size();
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(of = "uuid")
|
||||
protected static class SessionPlayer {
|
||||
|
@ -3,14 +3,11 @@ 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DebugSession extends Session {
|
||||
@ -52,7 +49,7 @@ public class DebugSession extends Session {
|
||||
sessionPlayer.setPlayer(player);
|
||||
|
||||
notifyJoined(sessionPlayer.toData());
|
||||
Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData()));
|
||||
notifyLobby();
|
||||
|
||||
return sessionPlayer.getUuid();
|
||||
}
|
||||
@ -60,19 +57,13 @@ public class DebugSession extends Session {
|
||||
@Override
|
||||
protected void startGame() {}
|
||||
|
||||
public void close() {
|
||||
for (var sessionPlayer : getPlayers().values()) {
|
||||
try {
|
||||
var player = sessionPlayer.getPlayer();
|
||||
if (player != null) {
|
||||
player.disconnect();
|
||||
}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyPlayers(ServerMessage message) {
|
||||
super.notifyPlayers(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import eu.jonahbauer.wizard.common.messages.server.Response;
|
||||
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
|
||||
import eu.jonahbauer.wizard.server.machine.states.CreatedState;
|
||||
import lombok.SneakyThrows;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
@ -44,8 +45,16 @@ public class Player extends Context<ClientState, Player> {
|
||||
shouldBuffer = Response.class;
|
||||
}
|
||||
|
||||
public void disconnect() throws IOException {
|
||||
session.close(CloseStatus.SERVER_ERROR);
|
||||
public void disconnect() {
|
||||
disconnect(null);
|
||||
}
|
||||
|
||||
public void disconnect(@Nullable String reason) {
|
||||
try {
|
||||
session.close(new CloseStatus(CloseStatus.GOING_AWAY.getCode(), reason));
|
||||
} catch (IOException ignored) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
|
@ -0,0 +1,11 @@
|
||||
package eu.jonahbauer.wizard.server.management;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface LobbyMBean {
|
||||
|
||||
int getPlayerCount();
|
||||
|
||||
int getTotalPlayerCount();
|
||||
|
||||
int getSessionCount();
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package eu.jonahbauer.wizard.server.management;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface SessionMBean {
|
||||
|
||||
UUID getUuid();
|
||||
|
||||
String getName();
|
||||
|
||||
int getPlayerCount();
|
||||
|
||||
boolean isRunning();
|
||||
|
||||
boolean isDebug();
|
||||
|
||||
void close();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user