diff --git a/Server/src/main/java/uulm/teamname/marvelous/server/lobby/Lobby.java b/Server/src/main/java/uulm/teamname/marvelous/server/lobby/Lobby.java index 0e1949e..a9cc2a4 100644 --- a/Server/src/main/java/uulm/teamname/marvelous/server/lobby/Lobby.java +++ b/Server/src/main/java/uulm/teamname/marvelous/server/lobby/Lobby.java @@ -1,6 +1,7 @@ package uulm.teamname.marvelous.server.lobby; import org.tinylog.Logger; +import uulm.teamname.marvelous.gamelibrary.entities.EntityType; import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.events.EventBuilder; import uulm.teamname.marvelous.gamelibrary.events.EventType; @@ -24,6 +25,7 @@ public class Lobby { private Participant activePlayer; private int badRequests; private PauseSegment pauseSegment; + private final TurnTimer turnTimer; public Lobby( String gameID, @@ -40,7 +42,7 @@ public class Lobby { partyConfig, characterConfig, scenarioConfig - ); //TODO: Add config objects here + ); this.pipeline = new Pipeline(); @@ -53,6 +55,10 @@ public class Lobby { .addSegment(pauseSegment) .addSegment(disconnectSegment) .addSegment(gameStateSegment); + + this.turnTimer = new TurnTimer( + partyConfig.maxRoundTime, + this::turnTimeout); } /** @@ -60,7 +66,7 @@ public class Lobby { * @param requests to be processed * @param source the player executing the requests */ - public void receiveRequests(Request[] requests, Participant source) { + public synchronized void receiveRequests(Request[] requests, Participant source) { if(activePlayer != source && source.type != ParticipantType.Spectator) { activePlayer = source; badRequests = 0; @@ -70,6 +76,7 @@ public class Lobby { Logger.trace("Processing requests through pipeline"); Optional resultingEvents = pipeline.processRequests(requests, source); + Logger.debug("generated {} events from the pipeline", resultingEvents.map(x -> x.length).orElse(0)); //resultingEvents isEmpty when a wrong request appeared if (resultingEvents.isEmpty()) { @@ -79,13 +86,25 @@ public class Lobby { connection.sendEvents(source, events); badRequests = 0; } + + + EntityType currentActiveCharacterType = game.state.getActiveCharacter().type; + if (pauseSegment.isPaused()) { + turnTimer.clear(); + } else if (currentActiveCharacterType == EntityType.P1) { + turnTimer.startTurnTimer(connection.getPlayer1()); + } else if (currentActiveCharacterType == EntityType.P2) { + turnTimer.startTurnTimer(connection.getPlayer2()); + } else { + turnTimer.clear(); + } } /** * If the player executed a false request the request gets rejected. * @param source the executing player */ - private void reject(Participant source) { + private synchronized void reject(Participant source) { connection.sendEvents(source, new EventBuilder(EventType.Nack).buildGameEvent(), game.getGameStateEvent()); badRequests ++; //if the player sends 2 bad messages after one another, the player gets kicked out of the lobby. @@ -104,7 +123,7 @@ public class Lobby { * Warns the player he get timeouted soon. * @param source soon to be timeouted player */ - public void soonTimeout (Participant source){ + public synchronized void soonTimeout (Participant source){ connection.sendEvents( source, new EventBuilder(EventType.TimeoutWarningEvent).buildGameStateEvent()); @@ -114,7 +133,7 @@ public class Lobby { * If a player times out the other player automatically wins. * @param source is the timeouted player */ - public void Timeout(Participant source){ + public synchronized void timeout(Participant source){ connection.sendEvents( source, new EventBuilder(EventType.TimeoutEvent).buildGameStateEvent()); @@ -131,13 +150,18 @@ public class Lobby { } } + public synchronized void turnTimeout(Participant source){ + //source round is over next players turn + connection.sendEvents(source, game.endTurn().toArray(new Event[0])); + } + /** * The method generates a Win event for a {@link Participant}. * Afterwards it sends a Disconnect to everyone, and terminates the connection. * * @param winner is the {@link Participant} that won */ - public void generateWin(Participant winner){ + public synchronized void generateWin(Participant winner){ connection.broadcastEvents( new EventBuilder(EventType.WinEvent) .withPlayerWon(winner.type.equals(ParticipantType.PlayerOne) ? 1 : 2) diff --git a/Server/src/main/java/uulm/teamname/marvelous/server/lobby/RoundTimer.java b/Server/src/main/java/uulm/teamname/marvelous/server/lobby/RoundTimer.java deleted file mode 100644 index 232031a..0000000 --- a/Server/src/main/java/uulm/teamname/marvelous/server/lobby/RoundTimer.java +++ /dev/null @@ -1,31 +0,0 @@ -package uulm.teamname.marvelous.server.lobby; - -import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType; -import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType; -import uulm.teamname.marvelous.server.lobbymanager.Participant; - -import java.util.Timer; -import java.util.TimerTask; - -public class RoundTimer { - private final Timer timer; - private final Lobby parent; - private final int time; - - public RoundTimer(int maxRoundTime, Lobby parent) { - this.timer = new Timer(); - time = maxRoundTime; - this.parent = parent; - } - - public void startRoundTimer(Participant p) { - if (p.type == ParticipantType.Spectator) throw new IllegalStateException("Spectators don't have TurnTime"); - timer.cancel(); -// timer.schedule(new TimerTask() { -// @Override -// public void run() { -// // TODO: skip current round -// } -// }); - } -} diff --git a/Server/src/main/java/uulm/teamname/marvelous/server/lobby/TurnTimer.java b/Server/src/main/java/uulm/teamname/marvelous/server/lobby/TurnTimer.java new file mode 100644 index 0000000..5e5147b --- /dev/null +++ b/Server/src/main/java/uulm/teamname/marvelous/server/lobby/TurnTimer.java @@ -0,0 +1,39 @@ +package uulm.teamname.marvelous.server.lobby; + +import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType; +import uulm.teamname.marvelous.server.lobbymanager.Participant; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.function.Consumer; + +public class TurnTimer { + private final Timer timer; + private final Consumer callback; + private final int maxRoundTime; + + public TurnTimer(int maxRoundTime, Consumer callback) { + this.timer = new Timer(); + this.maxRoundTime = maxRoundTime; + this.callback = callback; + } + + public void startTurnTimer(Participant participant) { + if (participant.type == ParticipantType.Spectator) + throw new IllegalStateException("Spectators don't have TurnTime"); + + // cancel all current timers, and start a new timer + timer.cancel(); + timer.schedule(new TimerTask() { + @Override + public void run() { + callback.accept(participant); + } + }, maxRoundTime); + } + + /** cancels all currently running timers */ + public void clear() { + timer.cancel(); + } +}