Server/Server/src/main/java/uulm/teamname/marvelous/server/lobby/pipelining/PauseSegment.java

124 lines
4.7 KiB
Java

package uulm.teamname.marvelous.server.lobby.pipelining;
import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.events.Event;
import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
import uulm.teamname.marvelous.gamelibrary.events.EventType;
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
import uulm.teamname.marvelous.gamelibrary.requests.RequestBuilder;
import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* The {@link PauseSegment} can pause and unpause a game.
*/
public class PauseSegment implements Segment {
private boolean paused;
public PauseSegment() {
paused = false;
}
/** This method pauses the game if it is not already paused.*/
public void pauseGame() {
if (!paused) {
paused = true;
Logger.debug("Game paused.");
}
}
/**
* This method ends a paused game.
*/
public void pauseEnd() {
if (paused) {
paused = false;
Logger.debug("Game unpaused.");
}
}
public boolean isPaused() {
return paused;
}
/**
* Pipelining method to process a set of requests. The list of requests will be processed according to the following
* rules:
* <ul>
* <li>If there is a PauseStartRequest, the paused value will be set to true</li>
* <li>Any CharacterRequests will be removed from the requests if the game is paused. These include:
* <ul>
* <li>MeeleAttackRequest</li>
* <li>RangedAttackRequest</li>
* <li>MoveRequest</li>
* <li>ExchangeInfinityStoneRequest</li>
* <li>UseInfinityStoneRequest</li>
* <li>EndRoundRequest</li>
* </ul>
* </li>
* <li>If a mistake is made (request is sent while pause active), the client will get an error</li>
* <li>If there is a PauseStopRequest the game will be unpaused</li>
* </ul>
*/
@Override
public void processRequests(Packet packet, List<Event> carrier, AtomicBoolean abort) {
Logger.trace("PauseSegment received {} requests. PausedState is {}",
packet.size(),
paused);
// check if there is a pause request (either start or stop)
if (packet.contains(new RequestBuilder(RequestType.PauseStartRequest).buildGameRequest())) {
Logger.trace("PauseStartRequest found");
if(packet.getOrigin().type == ParticipantType.Spectator || packet.getOrigin().isAI) {
Logger.trace("Invalid pause start request. Aborting");
abort.set(true);
return;
}
if (!paused) {
// pause the game
pauseGame();
// create a new PauseStartEvent
carrier.add(new EventBuilder(EventType.PauseStartEvent).buildGameEvent());
Logger.trace("Added PauseStartEvent to pipeline carrier");
} else { // if the game is already paused
Logger.info("PauseStartRequest sent even though the game wasn't paused. Error triggered.");
abort.set(true);
return;
}
} else if (packet.contains(new RequestBuilder(RequestType.PauseStopRequest).buildGameRequest())) {
Logger.trace("PauseStopRequest found");
if(packet.getOrigin().type == ParticipantType.Spectator || packet.getOrigin().isAI) {
Logger.trace("Invalid pause stop request. Aborting");
abort.set(true);
return;
}
if (paused) {
pauseEnd();
Logger.debug("Game unpaused.");
// create a new PauseStartRequest
carrier.add(new EventBuilder(EventType.PauseStopEvent).buildGameEvent());
Logger.trace("Added PauseStopEvent to pipeline carrier");
} else { // if the game is not paused
Logger.info("PauseStopRequest sent even though the game wasn't paused. Error triggered.");
abort.set(true);
return;
}
}
if (paused) {
Logger.trace("As the game is paused, Requests are removed.");
packet.removeRequestsOfTypes(
RequestType.MeleeAttackRequest,
RequestType.RangedAttackRequest,
RequestType.MoveRequest,
RequestType.ExchangeInfinityStoneRequest,
RequestType.UseInfinityStoneRequest,
RequestType.EndRoundRequest);
}
packet.removeRequestsOfTypes(RequestType.PauseStopRequest, RequestType.PauseStartRequest);
}
}