added debug websocket
This commit is contained in:
parent
3b31c752cb
commit
66172c20cb
@ -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…
x
Reference in New Issue
Block a user