added debug websocket

main
Jonah Bauer 3 years ago
parent 0f3d3e929d
commit ec77b05b0d

@ -5,7 +5,10 @@ import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import eu.jonahbauer.wizard.common.messages.server.SessionCreatedMessage;
import eu.jonahbauer.wizard.common.messages.server.SessionListMessage;
import eu.jonahbauer.wizard.common.messages.server.SessionRemovedMessage;
import eu.jonahbauer.wizard.common.model.Configuration;
import eu.jonahbauer.wizard.server.debug.DebugSession;
import eu.jonahbauer.wizard.server.machine.Player;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@ -44,6 +47,22 @@ public class Lobby {
}
}
public DebugSession createDebugSession(@NotNull String name, long timeout, @NotNull Configuration configuration) {
lock.readLock().lock();
try {
DebugSession session;
do {
session = new DebugSession(UUID.randomUUID(), name, timeout, configuration);
} while (sessions.putIfAbsent(session.getUuid(), session) != null);
notifyPlayers(new SessionCreatedMessage(session.toData()));
return session;
} finally {
lock.readLock().unlock();
}
}
public Session getSession(UUID uuid) {
return sessions.get(uuid);
}

@ -26,15 +26,15 @@ import java.util.concurrent.ThreadLocalRandom;
@Log4j2
@EqualsAndHashCode(of = "uuid")
public class Session implements Observer {
private static final int MIN_PLAYERS = 3;
private static final int MAX_PLAYERS = 6;
protected static final int MIN_PLAYERS = 3;
protected static final int MAX_PLAYERS = 6;
private final UUID uuid;
private final String name;
private final long timeout;
private final Configuration configuration;
@Getter(AccessLevel.NONE)
@Getter(AccessLevel.PROTECTED)
private final Map<UUID, SessionPlayer> players = new LinkedHashMap<>();
private Game game;
@ -174,7 +174,7 @@ public class Session implements Observer {
}
}
private void startGame() {
protected void startGame() {
notifyPlayers(new StartingGameMessage());
messages.add(Pair.of(null, new StartingGameMessage()));
game = new Game(Configurations.get(configuration).withTimeout(timeout), this);
@ -204,7 +204,7 @@ public class Session implements Observer {
});
}
private void notifyJoined(PlayerData joined) {
protected void notifyJoined(PlayerData joined) {
var message = new PlayerJoinedMessage(joined);
for (SessionPlayer player : players.values()) {
if (player.getUuid().equals(joined.getUuid())) {
@ -220,7 +220,7 @@ public class Session implements Observer {
}
}
private void notifyPlayers(ServerMessage message) {
protected void notifyPlayers(ServerMessage message) {
for (SessionPlayer player : players.values()) {
player.send(message);
}
@ -246,7 +246,7 @@ public class Session implements Observer {
@Data
@EqualsAndHashCode(of = "uuid")
private static class SessionPlayer {
protected static class SessionPlayer {
private final UUID uuid;
private final String name;
private final String secret = generateSecret();

@ -0,0 +1,75 @@
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 {
public DebugSession(UUID uuid, String name, long timeout, Configuration configuration) {
super(uuid, name, timeout, configuration);
var dummy1 = new SessionPlayer(new UUID(0, 1), "Dummy #1");
var dummy2 = new SessionPlayer(new UUID(0, 2), "Dummy #2");
var dummy3 = new SessionPlayer(new UUID(0, 3), "Dummy #3");
var dummy4 = new SessionPlayer(new UUID(0, 4), "Dummy #4");
getPlayers().put(dummy1.getUuid(), dummy1);
getPlayers().put(dummy2.getUuid(), dummy2);
getPlayers().put(dummy3.getUuid(), dummy3);
getPlayers().put(dummy4.getUuid(), dummy4);
}
@Override
public synchronized void handlePlayerMessage(UUID uuid, PlayerMessage message) {
var player = getPlayers().get(uuid);
if (player == null) {
throw new NackException(NackMessage.PLAYER_NOT_FOUND, "Who are you?");
}
}
public synchronized UUID join(Player player, String name) {
if (getGame() != null) {
throw new NackException(NackMessage.GAME_ALREADY_STARTED, "Game has already started.");
} else if (getPlayers().size() == MAX_PLAYERS) {
throw new NackException(NackMessage.SESSION_FULL, "Session is full.");
} else if (getPlayers().values().stream().anyMatch(p -> p.getName().equalsIgnoreCase(name))) {
throw new NackException(NackMessage.NAME_TAKEN, "Name is already taken.");
}
SessionPlayer sessionPlayer;
long i = 0;
do {
sessionPlayer = new SessionPlayer(new UUID(0, i++), name);
} while (getPlayers().putIfAbsent(sessionPlayer.getUuid(), sessionPlayer) != null);
sessionPlayer.setPlayer(player);
notifyJoined(sessionPlayer.toData());
Lobby.getInstance().notifyPlayers(new SessionModifiedMessage(toData()));
return sessionPlayer.getUuid();
}
@Override
protected void startGame() {}
public void close() {
for (var player : getPlayers().values()) {
try {
player.getPlayer().disconnect();
} catch (IOException ignored) {}
}
}
@Override
public void notifyPlayers(ServerMessage message) {
super.notifyPlayers(message);
}
}

@ -0,0 +1,61 @@
package eu.jonahbauer.wizard.server.debug;
import eu.jonahbauer.wizard.common.messages.ParseException;
import eu.jonahbauer.wizard.common.messages.observer.ObserverMessage;
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import eu.jonahbauer.wizard.common.model.Configuration;
import eu.jonahbauer.wizard.server.Lobby;
import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Log4j2
@Component
@Profile("debug")
public class DebugSocketHandler extends TextWebSocketHandler {
private final Map<String, DebugSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(@NotNull WebSocketSession session) {
var dummySession = Lobby.getInstance().createDebugSession("Debug Session", 10, Configuration.DEFAULT);
sessions.put(session.getId(), dummySession);
log.info("Dummy connection #{} from {}.", session.getId(), session.getRemoteAddress());
}
@Override
protected void handleTextMessage(@NotNull WebSocketSession session, @NotNull TextMessage text) throws IOException {
var dummySession = sessions.get(session.getId());
for (String line : text.getPayload().lines().toArray(String[]::new)) {
try {
dummySession.notify(ObserverMessage.parse(line));
} catch (ParseException e) {
try {
dummySession.notifyPlayers(ServerMessage.parse(line));
} catch (ParseException e2) {
var nack = new NackMessage(NackMessage.MALFORMED_MESSAGE,"Could not parse " + text.getPayload() + ".").toString();
session.sendMessage(new TextMessage(nack));
}
}
}
}
@Override
public void afterConnectionClosed(@NotNull WebSocketSession session, @NotNull CloseStatus status) {
var dummySession = sessions.get(session.getId());
dummySession.close();
Lobby.getInstance().removeSession(dummySession.getUuid());
log.info("Dummy connection #{} closed {}.", session.getId(), status);
}
}

@ -0,0 +1,26 @@
package eu.jonahbauer.wizard.server.debug;
import lombok.AccessLevel;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@Profile("debug")
public class DebugWebSocketConfig implements WebSocketConfigurer {
@Getter(AccessLevel.PRIVATE)
private final DebugSocketHandler debugSocketHandler;
public DebugWebSocketConfig(DebugSocketHandler debugSocketHandler) {
this.debugSocketHandler = debugSocketHandler;
}
@Override
public void registerWebSocketHandlers(@NotNull WebSocketHandlerRegistry registry) {
registry.addHandler(this.getDebugSocketHandler(), "/debug").setAllowedOrigins("*");
}
}

@ -10,6 +10,7 @@ import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.util.ArrayList;
public class Player extends Context<ClientState, Player> {
@ -43,6 +44,10 @@ public class Player extends Context<ClientState, Player> {
shouldBuffer = Response.class;
}
public void disconnect() throws IOException {
session.close(CloseStatus.SERVER_ERROR);
}
@SneakyThrows
public void send(ServerMessage message) {
synchronized (session) {

Loading…
Cancel
Save