mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 19:04:49 +00:00
Compare commits
2 Commits
a60c702306
...
4d31a8ed44
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d31a8ed44 | ||
|
|
fc47d81b8e |
@@ -22,11 +22,13 @@ import org.toop.framework.eventbus.EventFlow;
|
|||||||
import org.toop.framework.eventbus.GlobalEventBus;
|
import org.toop.framework.eventbus.GlobalEventBus;
|
||||||
import org.toop.framework.game.BitboardGame;
|
import org.toop.framework.game.BitboardGame;
|
||||||
import org.toop.framework.game.games.reversi.BitboardReversi;
|
import org.toop.framework.game.games.reversi.BitboardReversi;
|
||||||
|
import org.toop.framework.game.games.tictactoe.BitboardTicTacToe;
|
||||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||||
import org.toop.framework.networking.connection.NetworkingClientEventListener;
|
import org.toop.framework.networking.connection.NetworkingClientEventListener;
|
||||||
import org.toop.framework.networking.connection.NetworkingClientManager;
|
import org.toop.framework.networking.connection.NetworkingClientManager;
|
||||||
import org.toop.framework.networking.server.GameDefinition;
|
import org.toop.framework.networking.server.GameDefinition;
|
||||||
import org.toop.framework.networking.server.MasterServer;
|
import org.toop.framework.networking.server.MasterServer;
|
||||||
|
import org.toop.framework.networking.server.Server;
|
||||||
import org.toop.framework.resource.ResourceLoader;
|
import org.toop.framework.resource.ResourceLoader;
|
||||||
import org.toop.framework.resource.ResourceManager;
|
import org.toop.framework.resource.ResourceManager;
|
||||||
import org.toop.framework.resource.events.AssetLoaderEvents;
|
import org.toop.framework.resource.events.AssetLoaderEvents;
|
||||||
@@ -36,6 +38,7 @@ import org.toop.framework.resource.resources.SoundEffectAsset;
|
|||||||
import org.toop.local.AppContext;
|
import org.toop.local.AppContext;
|
||||||
import org.toop.local.AppSettings;
|
import org.toop.local.AppSettings;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@@ -98,6 +101,17 @@ public final class App extends Application {
|
|||||||
|
|
||||||
WidgetContainer.setCurrentView(loading);
|
WidgetContainer.setCurrentView(loading);
|
||||||
|
|
||||||
|
var games = new ConcurrentHashMap<String, Class<? extends TurnBasedGame>>();
|
||||||
|
games.put("tictactoe", BitboardTicTacToe.class);
|
||||||
|
games.put("reversi", BitboardReversi.class);
|
||||||
|
|
||||||
|
var a = new MasterServer(6666, games, Duration.ofSeconds(5));
|
||||||
|
try {
|
||||||
|
a.start();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
setOnLoadingSuccess(loading);
|
setOnLoadingSuccess(loading);
|
||||||
|
|
||||||
EventFlow loadingFlow = new EventFlow();
|
EventFlow loadingFlow = new EventFlow();
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.toop.framework.networking.server;
|
||||||
|
|
||||||
|
import org.toop.framework.SnowflakeGenerator;
|
||||||
|
|
||||||
|
public class GameChallenge {
|
||||||
|
private final long id = SnowflakeGenerator.nextId(); // I don't need this, but the tournament server uses it...
|
||||||
|
|
||||||
|
private final ServerUser from;
|
||||||
|
private final ServerUser to;
|
||||||
|
private final String gameType;
|
||||||
|
private final SimpleTimer timer;
|
||||||
|
|
||||||
|
private boolean isChallengeAccepted = false;
|
||||||
|
|
||||||
|
public GameChallenge(ServerUser from, ServerUser to, String gameType, SimpleTimer timer) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.gameType = gameType;
|
||||||
|
this.timer = timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerUser[] getUsers() {
|
||||||
|
return new ServerUser[]{from, to};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forceExpire() {
|
||||||
|
timer.forceExpire();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String acceptChallenge() {
|
||||||
|
isChallengeAccepted = true;
|
||||||
|
timer.forceExpire();
|
||||||
|
return gameType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpired() {
|
||||||
|
return timer.isExpired();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.toop.framework.networking.server;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public class GameChallengeTimer implements SimpleTimer {
|
||||||
|
|
||||||
|
private final Instant createdAt;
|
||||||
|
private final Duration timeout;
|
||||||
|
|
||||||
|
private boolean isExpired = false;
|
||||||
|
|
||||||
|
public GameChallengeTimer(Duration duration) {
|
||||||
|
this.createdAt = Instant.now();
|
||||||
|
this.timeout = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forceExpire() {
|
||||||
|
this.isExpired = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExpired() {
|
||||||
|
if (this.isExpired) return true;
|
||||||
|
return Instant.now().isAfter(createdAt.plus(timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long secondsRemaining() {
|
||||||
|
return Duration.between(Instant.now(), createdAt.plus(timeout)).toSeconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,15 +15,16 @@ import org.toop.framework.SnowflakeGenerator;
|
|||||||
import org.toop.framework.game.BitboardGame;
|
import org.toop.framework.game.BitboardGame;
|
||||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class MasterServer {
|
public class MasterServer {
|
||||||
private final int port;
|
private final int port;
|
||||||
public final Server gs;
|
public final Server gs;
|
||||||
|
|
||||||
public MasterServer(int port, Map<String, Class<? extends TurnBasedGame>> gameTypes) {
|
public MasterServer(int port, Map<String, Class<? extends TurnBasedGame>> gameTypes, Duration challengeDuration) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.gs = new Server(gameTypes);
|
this.gs = new Server(gameTypes, challengeDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() throws InterruptedException {
|
public void start() throws InterruptedException {
|
||||||
|
|||||||
@@ -1,23 +1,35 @@
|
|||||||
package org.toop.framework.networking.server;
|
package org.toop.framework.networking.server;
|
||||||
|
|
||||||
import org.toop.framework.game.BitboardGame;
|
|
||||||
import org.toop.framework.game.players.LocalPlayer;
|
import org.toop.framework.game.players.LocalPlayer;
|
||||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||||
import org.toop.framework.gameFramework.model.player.Player;
|
import org.toop.framework.gameFramework.model.player.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.*;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
public class Server implements GameServer {
|
public class Server implements GameServer {
|
||||||
|
|
||||||
final private Map<String, Class<? extends TurnBasedGame>> gameTypes;
|
final private Map<String, Class<? extends TurnBasedGame>> gameTypes;
|
||||||
final private List<OnlineGame<TurnBasedGame>> games = new ArrayList<>();
|
|
||||||
final private Map<Long, ServerUser> users = new ConcurrentHashMap<>();
|
final private Map<Long, ServerUser> users = new ConcurrentHashMap<>();
|
||||||
|
final private List<GameChallenge> gameChallenges = new CopyOnWriteArrayList<>();
|
||||||
|
final private List<OnlineGame<TurnBasedGame>> games = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public Server(Map<String, Class<? extends TurnBasedGame>> gameTypes) {
|
final private Duration challengeDuration;
|
||||||
|
final private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
|
public Server(Map<String, Class<? extends TurnBasedGame>> gameTypes, Duration challengeDuration) {
|
||||||
this.gameTypes = gameTypes;
|
this.gameTypes = gameTypes;
|
||||||
|
this.challengeDuration = challengeDuration;
|
||||||
|
|
||||||
|
scheduler.schedule(this::serverTask, 0, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serverTask() {
|
||||||
|
checkChallenges();
|
||||||
|
scheduler.schedule(this::serverTask, 500, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUser(ServerUser user) {
|
public void addUser(ServerUser user) {
|
||||||
@@ -36,6 +48,96 @@ public class Server implements GameServer {
|
|||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerUser getUser(String username) {
|
||||||
|
return users.values().stream().filter(e -> e.name().equalsIgnoreCase(username)).findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerUser getUser(long id) {
|
||||||
|
return users.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void challengeUser(String fromUser, String toUser, String gameType) {
|
||||||
|
|
||||||
|
ServerUser from = getUser(fromUser);
|
||||||
|
if (from == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameTypes.containsKey(gameType)) {
|
||||||
|
from.sendMessage("ERR gametype not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerUser to = getUser(toUser);
|
||||||
|
if (to == null) {
|
||||||
|
from.sendMessage("ERR user not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ch = new GameChallenge(from, to, gameType, new GameChallengeTimer(challengeDuration));
|
||||||
|
|
||||||
|
to.sendMessage(
|
||||||
|
"\"SVR GAME CHALLENGE {CHALLENGER: \"%s\", GAMETYPE: \"%s\", CHALLENGENUMBER: \"%s\"}"
|
||||||
|
.formatted(from.name(), gameType, ch.id())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isValidChallenge(ch)) {
|
||||||
|
warnUserExpiredChallenge(from, ch.id());
|
||||||
|
ch.forceExpire();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gameChallenges.addLast(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void warnUserExpiredChallenge(ServerUser user, long challengeId) {
|
||||||
|
user.sendMessage("SVR GAME CHALLENGE CANCELLED {CHALLENGENUMBER: \"" + challengeId + "\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidChallenge(GameChallenge gameChallenge) {
|
||||||
|
for (var user : gameChallenge.getUsers()) {
|
||||||
|
if (users.get(user.id()) == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.games().length > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameChallenge.isExpired()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkChallenges() {
|
||||||
|
for (int i = gameChallenges.size() - 1; i >= 0; i--) {
|
||||||
|
var challenge = gameChallenges.get(i);
|
||||||
|
|
||||||
|
if (isValidChallenge(challenge)) continue;
|
||||||
|
|
||||||
|
if (challenge.isExpired()) {
|
||||||
|
Arrays.stream(challenge.getUsers()).forEach(user -> warnUserExpiredChallenge(user, challenge.id()));
|
||||||
|
gameChallenges.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptChallenge(long challengeId) {
|
||||||
|
for (var challenge : gameChallenges) {
|
||||||
|
if (challenge.id() == challengeId) {
|
||||||
|
startGame(challenge.acceptChallenge(), (User[]) challenge.getUsers());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GameChallenge> gameChallenges() {
|
||||||
|
return gameChallenges;
|
||||||
|
}
|
||||||
|
|
||||||
public void startGame(String gameType, User... users) {
|
public void startGame(String gameType, User... users) {
|
||||||
if (!gameTypes.containsKey(gameType)) return;
|
if (!gameTypes.containsKey(gameType)) return;
|
||||||
|
|
||||||
@@ -53,7 +155,22 @@ public class Server implements GameServer {
|
|||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public void checkGames() {
|
||||||
|
// for (int i = games.size() - 1; i >= 0; i--) {
|
||||||
|
// var game = games.get(i);
|
||||||
|
// if (game.game().getWinner() >= 0) games.remove(i);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public String[] onlineUsers() {
|
public String[] onlineUsers() {
|
||||||
return users.values().stream().map(ServerUser::name).toArray(String[]::new);
|
return users.values().stream().map(ServerUser::name).toArray(String[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void closeServer() {
|
||||||
|
scheduler.shutdown();
|
||||||
|
gameChallenges.clear();
|
||||||
|
games.clear();
|
||||||
|
users.clear();
|
||||||
|
gameTypes.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,28 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleChallenge(ParsedMessage p) {
|
private void handleChallenge(ParsedMessage p) {
|
||||||
// TODO
|
if(!allowedArgs(p.args())) return;
|
||||||
|
if (p.args().length < 2) return;
|
||||||
|
|
||||||
|
if (p.args()[0].equalsIgnoreCase("accept")) {
|
||||||
|
try {
|
||||||
|
long id = Long.parseLong(p.args()[1]);
|
||||||
|
|
||||||
|
if (id <= 0) {
|
||||||
|
user.sendMessage("ERR id must be a positive number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.acceptChallenge(id);
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
user.sendMessage("ERR id is not a valid number or too big");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.challengeUser(user.name(), p.args()[0], p.args()[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMove(ParsedMessage p) {
|
private void handleMove(ParsedMessage p) {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.toop.framework.networking.server;
|
package org.toop.framework.networking.server;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
public interface ServerUser {
|
public interface ServerUser {
|
||||||
long id();
|
long id();
|
||||||
String name();
|
String name();
|
||||||
|
Game[] games();
|
||||||
|
void addGame(Game game);
|
||||||
|
void removeGame(Game game);
|
||||||
void setName(String name);
|
void setName(String name);
|
||||||
|
void sendMessage(String message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.toop.framework.networking.server;
|
||||||
|
|
||||||
|
public interface SimpleTimer {
|
||||||
|
void forceExpire();
|
||||||
|
boolean isExpired();
|
||||||
|
long secondsRemaining();
|
||||||
|
}
|
||||||
@@ -2,11 +2,13 @@ package org.toop.framework.networking.server;
|
|||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class User implements ServerUser {
|
public class User implements ServerUser {
|
||||||
final private long id;
|
final private long id;
|
||||||
private String name;
|
private String name;
|
||||||
|
private final List<Game> games = new ArrayList<>();
|
||||||
private ChannelHandlerContext connectionContext;
|
private ChannelHandlerContext connectionContext;
|
||||||
|
|
||||||
public User(long userId, String name) {
|
public User(long userId, String name) {
|
||||||
@@ -24,11 +26,34 @@ public class User implements ServerUser {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addGame(Game game) {
|
||||||
|
games.add(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeGame(Game game) {
|
||||||
|
games.remove(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game[] games() {
|
||||||
|
return games.toArray(new Game[0]);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
IO.println(message);
|
||||||
|
ctx().channel().writeAndFlush(message);
|
||||||
|
}
|
||||||
|
|
||||||
public ChannelHandlerContext ctx() {
|
public ChannelHandlerContext ctx() {
|
||||||
return connectionContext;
|
return connectionContext;
|
||||||
}
|
}
|
||||||
@@ -37,4 +62,5 @@ public class User implements ServerUser {
|
|||||||
this.connectionContext = ctx;
|
this.connectionContext = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ import org.toop.framework.gameFramework.model.game.PlayResult;
|
|||||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||||
import org.toop.framework.gameFramework.model.player.Player;
|
import org.toop.framework.gameFramework.model.player.Player;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
public class ServerTest {
|
public class ServerTest {
|
||||||
|
|
||||||
static class TurnBasedGameMock implements TurnBasedGame {
|
static class TurnBasedGameMock implements TurnBasedGame {
|
||||||
@@ -66,7 +65,55 @@ public class ServerTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class TestUser implements ServerUser {
|
||||||
|
|
||||||
|
final private long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public TestUser(long id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game[] games() {
|
||||||
|
return new Game[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addGame(Game game) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeGame(Game game) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Server server;
|
private Server server;
|
||||||
|
private Duration waitTime = Duration.ofSeconds(2);
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
@@ -75,7 +122,7 @@ public class ServerTest {
|
|||||||
games.put("tictactoe", TurnBasedGameMock.class);
|
games.put("tictactoe", TurnBasedGameMock.class);
|
||||||
games.put("reversi", TurnBasedGameMock.class);
|
games.put("reversi", TurnBasedGameMock.class);
|
||||||
|
|
||||||
server = new Server(games);
|
server = new Server(games, waitTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -89,9 +136,32 @@ public class ServerTest {
|
|||||||
Assertions.assertArrayEquals(expected, actual);
|
Assertions.assertArrayEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testChallenge() {
|
||||||
|
server.addUser(new TestUser(1, "test1"));
|
||||||
|
server.addUser(new TestUser(2, "test2"));
|
||||||
|
server.challengeUser("test1", "test2", "tictactoe");
|
||||||
|
|
||||||
|
IO.println(server.gameChallenges());
|
||||||
|
|
||||||
|
Assertions.assertEquals(1, server.gameChallenges().size());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(waitTime.plusMillis(100));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertEquals(0, server.gameChallenges().size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testStartGame() {
|
void testStartGame() {
|
||||||
server.startGame("tictactoe", new User(0, "A"), new User(1, "B"));
|
server.startGame("tictactoe", new User(0, "A"), new User(1, "B"));
|
||||||
Assertions.assertEquals(1, server.ongoingGames().size());
|
Assertions.assertEquals(1, server.ongoingGames().size());
|
||||||
|
server.startGame("reversi", new User(0, "A"), new User(1, "B"));
|
||||||
|
Assertions.assertEquals(2, server.ongoingGames().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
$client = New-Object System.Net.Sockets.TcpClient("localhost", 6666)
|
||||||
|
$stream = $client.GetStream()
|
||||||
|
$writer = New-Object System.IO.StreamWriter($stream)
|
||||||
|
$reader = New-Object System.IO.StreamReader($stream)
|
||||||
|
|
||||||
|
$client2 = New-Object System.Net.Sockets.TcpClient("localhost", 6666)
|
||||||
|
$stream2 = $client2.GetStream()
|
||||||
|
$writer2 = New-Object System.IO.StreamWriter($stream2)
|
||||||
|
$reader2 = New-Object System.IO.StreamReader($stream2)
|
||||||
|
|
||||||
|
$writer.WriteLine("login john")
|
||||||
|
$writer.Flush()
|
||||||
|
$reader.ReadLine()
|
||||||
|
|
||||||
|
$writer2.WriteLine("login hendrik")
|
||||||
|
$writer2.Flush()
|
||||||
|
$reader2.ReadLine()
|
||||||
Reference in New Issue
Block a user