mirror of
https://github.com/2OOP/pism.git
synced 2026-02-05 03:14:50 +00:00
Working challenges
This commit is contained in:
@@ -1,21 +1,40 @@
|
||||
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, SimpleTimer timer) {
|
||||
public GameChallenge(ServerUser from, ServerUser to, String gameType, SimpleTimer timer) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.gameType = gameType;
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
public void acceptChallenge() {
|
||||
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() {
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.toop.framework.game.players.LocalPlayer;
|
||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||
import org.toop.framework.gameFramework.model.player.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
@@ -48,29 +49,88 @@ public class Server implements GameServer {
|
||||
}
|
||||
|
||||
public ServerUser getUser(String username) {
|
||||
return users.values().stream().filter(e -> e.name().equalsIgnoreCase(username)).findFirst().get();
|
||||
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) {
|
||||
public void challengeUser(String fromUser, String toUser, String gameType) {
|
||||
|
||||
ServerUser from = getUser(fromUser);
|
||||
if (from == null) {
|
||||
return;
|
||||
}
|
||||
ServerUser to = getUser(toUser);
|
||||
if (to == null) {
|
||||
|
||||
if (!gameTypes.containsKey(gameType)) {
|
||||
from.sendMessage("ERR gametype not found");
|
||||
return;
|
||||
}
|
||||
|
||||
gameChallenges.addLast(new GameChallenge(from, to, new GameChallengeTimer(challengeDuration)));
|
||||
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--) {
|
||||
if (gameChallenges.get(i).isExpired()) gameChallenges.remove(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,4 +165,12 @@ public class Server implements GameServer {
|
||||
public String[] onlineUsers() {
|
||||
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) {
|
||||
// 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) {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.toop.framework.networking.server;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public interface ServerUser {
|
||||
long id();
|
||||
String name();
|
||||
Game[] games();
|
||||
void addGame(Game game);
|
||||
void removeGame(Game game);
|
||||
void setName(String name);
|
||||
void sendMessage(String message);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package org.toop.framework.networking.server;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class User implements ServerUser {
|
||||
final private long id;
|
||||
private String name;
|
||||
private final List<Game> games = new ArrayList<>();
|
||||
private ChannelHandlerContext connectionContext;
|
||||
|
||||
public User(long userId, String name) {
|
||||
@@ -24,11 +26,34 @@ public class User implements ServerUser {
|
||||
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
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
IO.println(message);
|
||||
ctx().channel().writeAndFlush(message);
|
||||
}
|
||||
|
||||
public ChannelHandlerContext ctx() {
|
||||
return connectionContext;
|
||||
}
|
||||
@@ -37,4 +62,5 @@ public class User implements ServerUser {
|
||||
this.connectionContext = ctx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user