added name validation

main
Jonah Bauer 3 years ago
parent 26292fbd80
commit ceb5699778

@ -22,8 +22,11 @@ public final class AwaitingJoinSession extends Awaiting {
case NackMessage.GAME_ALREADY_STARTED -> client.println("Error: Game has already started."); case NackMessage.GAME_ALREADY_STARTED -> client.println("Error: Game has already started.");
case NackMessage.SESSION_FULL -> client.println("Error: The session is full."); case NackMessage.SESSION_FULL -> client.println("Error: The session is full.");
case NackMessage.SESSION_NOT_FOUND -> client.println("Error: Session not found."); case NackMessage.SESSION_NOT_FOUND -> client.println("Error: Session not found.");
case NackMessage.NAME_TAKEN -> client.println("Error: Name already taken."); case NackMessage.PLAYER_NAME_TAKEN -> client.println("Player name already taken.");
default -> { return super.onMessage(client, message); } case NackMessage.PLAYER_NAME_NOT_ALLOWED -> client.println("Player name not allowed.");
case NackMessage.SESSION_NAME_TAKEN -> client.println("Session name already taken.");
case NackMessage.SESSION_NAME_NOT_ALLOWED -> client.println("Session name not allowed.");
default -> client.println("Nack " + nack.getCode() + ": " + nack.getMessage());
} }
return Optional.of(new AwaitingJoinLobby()); return Optional.of(new AwaitingJoinLobby());
} else if (message instanceof SessionModifiedMessage || message instanceof SessionRemovedMessage) { } else if (message instanceof SessionModifiedMessage || message instanceof SessionRemovedMessage) {

@ -60,6 +60,7 @@ public class CreateGameScreen extends MenuScreen {
sessionName = new TextField("", skin); sessionName = new TextField("", skin);
sessionName.setPosition(WizardGame.WIDTH * 0.3f, WizardGame.HEIGHT * 0.5f); sessionName.setPosition(WizardGame.WIDTH * 0.3f, WizardGame.HEIGHT * 0.5f);
sessionName.setSize(0.4f * WizardGame.WIDTH, 64); sessionName.setSize(0.4f * WizardGame.WIDTH, 64);
sessionName.setMaxLength(20);
sessionName.addListener(errorListener); sessionName.addListener(errorListener);
sessionName.setProgrammaticChangeEvents(true); sessionName.setProgrammaticChangeEvents(true);

@ -120,6 +120,7 @@ public class LobbyScreen extends MenuScreen {
game.storage.playerName = playerName.getText(); game.storage.playerName = playerName.getText();
} }
}); });
playerName.setMaxLength(20);
playerName.addListener(new ResetErrorListener(skin)); playerName.addListener(new ResetErrorListener(skin));
labelSessionName = new Label("", skin, "textfield"); labelSessionName = new Label("", skin, "textfield");

@ -57,8 +57,11 @@ public final class AwaitingJoinSession extends Awaiting {
case NackMessage.GAME_ALREADY_STARTED -> log.error("Game has already started."); case NackMessage.GAME_ALREADY_STARTED -> log.error("Game has already started.");
case NackMessage.SESSION_FULL -> log.error("The session is full."); case NackMessage.SESSION_FULL -> log.error("The session is full.");
case NackMessage.SESSION_NOT_FOUND -> log.error("Session not found."); case NackMessage.SESSION_NOT_FOUND -> log.error("Session not found.");
case NackMessage.NAME_TAKEN -> log.error("Name already taken."); case NackMessage.PLAYER_NAME_TAKEN -> log.error("Player name already taken.");
default -> { return super.onMessage(client, message); } case NackMessage.PLAYER_NAME_NOT_ALLOWED -> log.error("Player name not allowed.");
case NackMessage.SESSION_NAME_TAKEN -> log.error("Session name already taken.");
case NackMessage.SESSION_NAME_NOT_ALLOWED -> log.error("Session name not allowed.");
default -> log.error("Nack {}: {}", nack.getCode(), nack.getMessage());
} }
return Optional.of(new AwaitingJoinLobby()); return Optional.of(new AwaitingJoinLobby());
} else if (message instanceof SessionModifiedMessage || message instanceof SessionRemovedMessage) { } else if (message instanceof SessionModifiedMessage || message instanceof SessionRemovedMessage) {

@ -12,10 +12,13 @@ public final class NackMessage extends ServerMessage implements Response {
public static final int UNEXPECTED_MESSAGE = 101; public static final int UNEXPECTED_MESSAGE = 101;
public static final int ILLEGAL_ARGUMENT = 200; public static final int ILLEGAL_ARGUMENT = 200;
public static final int NAME_TAKEN = 201;
public static final int NOT_FOUND = 210; public static final int NOT_FOUND = 210;
public static final int SESSION_NOT_FOUND = 211; public static final int SESSION_NOT_FOUND = 211;
public static final int PLAYER_NOT_FOUND = 212; public static final int PLAYER_NOT_FOUND = 212;
public static final int PLAYER_NAME_TAKEN = 220;
public static final int PLAYER_NAME_NOT_ALLOWED = 221;
public static final int SESSION_NAME_TAKEN = 230;
public static final int SESSION_NAME_NOT_ALLOWED = 231;
public static final int ILLEGAL_STATE = 300; public static final int ILLEGAL_STATE = 300;
public static final int GAME_ALREADY_STARTED = 301; public static final int GAME_ALREADY_STARTED = 301;

@ -1,12 +1,10 @@
package eu.jonahbauer.wizard.server; package eu.jonahbauer.wizard.server;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage; import eu.jonahbauer.wizard.common.messages.server.*;
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.common.model.Configuration;
import eu.jonahbauer.wizard.server.debug.DebugSession; import eu.jonahbauer.wizard.server.debug.DebugSession;
import eu.jonahbauer.wizard.server.machine.Player; import eu.jonahbauer.wizard.server.machine.Player;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
@ -14,6 +12,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Lobby { public class Lobby {
@Language("RegExp")
private static final String SESSION_NAME_PATTERN = "[a-zA-Z0-9_ ]{1,20}";
private static final Lobby INSTANCE = new Lobby(); private static final Lobby INSTANCE = new Lobby();
public static Lobby getInstance() { public static Lobby getInstance() {
return INSTANCE; return INSTANCE;
@ -26,8 +26,16 @@ public class Lobby {
private Lobby() {} private Lobby() {}
public Session createSession(@NotNull String name, long timeout, @NotNull Configuration configuration) { public Session createSession(@NotNull String name, long timeout, @NotNull Configuration configuration) {
if (!name.matches(SESSION_NAME_PATTERN)) {
throw new NackException(NackMessage.SESSION_NAME_NOT_ALLOWED, "Session name is too short, too long or contains illegal characters.");
}
lock.readLock().lock(); lock.readLock().lock();
try { try {
if (sessions.values().stream().anyMatch(s -> s.getName().equalsIgnoreCase(name))) {
throw new NackException(NackMessage.SESSION_NAME_TAKEN, "Session name is already taken.");
}
Session session; Session session;
do { do {
session = new Session(UUID.randomUUID(), name, timeout, configuration); session = new Session(UUID.randomUUID(), name, timeout, configuration);

@ -16,6 +16,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.intellij.lang.annotations.Language;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -26,6 +27,8 @@ import java.util.concurrent.ThreadLocalRandom;
@Log4j2 @Log4j2
@EqualsAndHashCode(of = "uuid") @EqualsAndHashCode(of = "uuid")
public class Session implements Observer { public class Session implements Observer {
@Language("RegExp")
private static final String PLAYER_NAME_PATTERN = "[a-zA-Z0-9_ ]{1,20}";
protected static final int MIN_PLAYERS = 3; protected static final int MIN_PLAYERS = 3;
protected static final int MAX_PLAYERS = 6; protected static final int MAX_PLAYERS = 6;
@ -63,7 +66,9 @@ public class Session implements Observer {
} else if (players.size() == MAX_PLAYERS) { } else if (players.size() == MAX_PLAYERS) {
throw new NackException(NackMessage.SESSION_FULL, "Session is full."); throw new NackException(NackMessage.SESSION_FULL, "Session is full.");
} else if (players.values().stream().anyMatch(p -> p.getName().equalsIgnoreCase(name))) { } else if (players.values().stream().anyMatch(p -> p.getName().equalsIgnoreCase(name))) {
throw new NackException(NackMessage.NAME_TAKEN, "Name is already taken."); throw new NackException(NackMessage.PLAYER_NAME_TAKEN, "Player name is already taken.");
} else if (!name.matches(PLAYER_NAME_PATTERN)) {
throw new NackException(NackMessage.PLAYER_NAME_NOT_ALLOWED, "Player name is too short, too long or contains illegal characters.");
} }
SessionPlayer sessionPlayer; SessionPlayer sessionPlayer;

@ -41,7 +41,7 @@ public class DebugSession extends Session {
} else if (getPlayers().size() == MAX_PLAYERS) { } else if (getPlayers().size() == MAX_PLAYERS) {
throw new NackException(NackMessage.SESSION_FULL, "Session is full."); throw new NackException(NackMessage.SESSION_FULL, "Session is full.");
} else if (getPlayers().values().stream().anyMatch(p -> p.getName().equalsIgnoreCase(name))) { } else if (getPlayers().values().stream().anyMatch(p -> p.getName().equalsIgnoreCase(name))) {
throw new NackException(NackMessage.NAME_TAKEN, "Name is already taken."); throw new NackException(NackMessage.PLAYER_NAME_TAKEN, "Player name is already taken.");
} }
SessionPlayer sessionPlayer; SessionPlayer sessionPlayer;

Loading…
Cancel
Save