feat: TurnTimer implemented properly

This commit is contained in:
Yannik Bretschneider 2021-06-04 14:26:45 +02:00
parent 68b078a90c
commit 207f70683b
3 changed files with 69 additions and 37 deletions

View File

@ -1,6 +1,7 @@
package uulm.teamname.marvelous.server.lobby; package uulm.teamname.marvelous.server.lobby;
import org.tinylog.Logger; import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.entities.EntityType;
import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.events.Event;
import uulm.teamname.marvelous.gamelibrary.events.EventBuilder; import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
import uulm.teamname.marvelous.gamelibrary.events.EventType; import uulm.teamname.marvelous.gamelibrary.events.EventType;
@ -24,6 +25,7 @@ public class Lobby {
private Participant activePlayer; private Participant activePlayer;
private int badRequests; private int badRequests;
private PauseSegment pauseSegment; private PauseSegment pauseSegment;
private final TurnTimer turnTimer;
public Lobby( public Lobby(
String gameID, String gameID,
@ -40,7 +42,7 @@ public class Lobby {
partyConfig, partyConfig,
characterConfig, characterConfig,
scenarioConfig scenarioConfig
); //TODO: Add config objects here );
this.pipeline = new Pipeline(); this.pipeline = new Pipeline();
@ -53,6 +55,10 @@ public class Lobby {
.addSegment(pauseSegment) .addSegment(pauseSegment)
.addSegment(disconnectSegment) .addSegment(disconnectSegment)
.addSegment(gameStateSegment); .addSegment(gameStateSegment);
this.turnTimer = new TurnTimer(
partyConfig.maxRoundTime,
this::turnTimeout);
} }
/** /**
@ -60,7 +66,7 @@ public class Lobby {
* @param requests to be processed * @param requests to be processed
* @param source the player executing the requests * @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) { if(activePlayer != source && source.type != ParticipantType.Spectator) {
activePlayer = source; activePlayer = source;
badRequests = 0; badRequests = 0;
@ -70,6 +76,7 @@ public class Lobby {
Logger.trace("Processing requests through pipeline"); Logger.trace("Processing requests through pipeline");
Optional<Event[]> resultingEvents = pipeline.processRequests(requests, source); Optional<Event[]> 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 //resultingEvents isEmpty when a wrong request appeared
if (resultingEvents.isEmpty()) { if (resultingEvents.isEmpty()) {
@ -79,13 +86,25 @@ public class Lobby {
connection.sendEvents(source, events); connection.sendEvents(source, events);
badRequests = 0; 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. * If the player executed a false request the request gets rejected.
* @param source the executing player * @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()); connection.sendEvents(source, new EventBuilder(EventType.Nack).buildGameEvent(), game.getGameStateEvent());
badRequests ++; badRequests ++;
//if the player sends 2 bad messages after one another, the player gets kicked out of the lobby. //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. * Warns the player he get timeouted soon.
* @param source soon to be timeouted player * @param source soon to be timeouted player
*/ */
public void soonTimeout (Participant source){ public synchronized void soonTimeout (Participant source){
connection.sendEvents( connection.sendEvents(
source, source,
new EventBuilder(EventType.TimeoutWarningEvent).buildGameStateEvent()); new EventBuilder(EventType.TimeoutWarningEvent).buildGameStateEvent());
@ -114,7 +133,7 @@ public class Lobby {
* If a player times out the other player automatically wins. * If a player times out the other player automatically wins.
* @param source is the timeouted player * @param source is the timeouted player
*/ */
public void Timeout(Participant source){ public synchronized void timeout(Participant source){
connection.sendEvents( connection.sendEvents(
source, source,
new EventBuilder(EventType.TimeoutEvent).buildGameStateEvent()); 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}. * The method generates a Win event for a {@link Participant}.
* Afterwards it sends a Disconnect to everyone, and terminates the connection. * Afterwards it sends a Disconnect to everyone, and terminates the connection.
* *
* @param winner is the {@link Participant} that won * @param winner is the {@link Participant} that won
*/ */
public void generateWin(Participant winner){ public synchronized void generateWin(Participant winner){
connection.broadcastEvents( connection.broadcastEvents(
new EventBuilder(EventType.WinEvent) new EventBuilder(EventType.WinEvent)
.withPlayerWon(winner.type.equals(ParticipantType.PlayerOne) ? 1 : 2) .withPlayerWon(winner.type.equals(ParticipantType.PlayerOne) ? 1 : 2)

View File

@ -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
// }
// });
}
}

View File

@ -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<Participant> callback;
private final int maxRoundTime;
public TurnTimer(int maxRoundTime, Consumer<Participant> 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();
}
}