fix: re-implemented the segment, this time properly

This commit is contained in:
Yannik Bretschneider 2021-07-07 18:04:19 +02:00
parent e02fd0879a
commit 09c5545c6d
4 changed files with 33 additions and 53 deletions

View File

@ -63,15 +63,13 @@ public class Lobby {
var reqSegment = new RequestGameStateSegment(this.game); var reqSegment = new RequestGameStateSegment(this.game);
this.pauseSegment = new PauseSegment(); this.pauseSegment = new PauseSegment();
var filterEndRoundRequestSegment = new FilterEndRoundRequestSegment(this::getActivePlayer); var filterEndRoundRequestSegment = new FilterEndRoundRequestSegment(game.state::getActiveCharacter);
var requestTurnEndSegment = new RequestTurnEndSegment(this.game);
var disconnectSegment = new DisconnectSegment(this); var disconnectSegment = new DisconnectSegment(this);
var gameLogicSegment = new GameLogicSegment(this.game); var gameLogicSegment = new GameLogicSegment(this.game);
pipeline.addSegment(reqSegment) pipeline.addSegment(reqSegment)
.addSegment(pauseSegment) .addSegment(pauseSegment)
.addSegment(filterEndRoundRequestSegment) .addSegment(filterEndRoundRequestSegment)
.addSegment(requestTurnEndSegment)
.addSegment(disconnectSegment) .addSegment(disconnectSegment)
.addSegment(gameLogicSegment); .addSegment(gameLogicSegment);

View File

@ -1,7 +1,11 @@
package uulm.teamname.marvelous.server.lobby.pipelining; package uulm.teamname.marvelous.server.lobby.pipelining;
import org.tinylog.Logger; import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
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.gamelogic.GameStateView;
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
import uulm.teamname.marvelous.gamelibrary.requests.RequestType; import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
import uulm.teamname.marvelous.server.lobbymanager.Participant; import uulm.teamname.marvelous.server.lobbymanager.Participant;
import uulm.teamname.marvelous.server.lobby.Lobby; import uulm.teamname.marvelous.server.lobby.Lobby;
@ -17,18 +21,18 @@ import java.util.function.Supplier;
*/ */
public class FilterEndRoundRequestSegment implements Segment { public class FilterEndRoundRequestSegment implements Segment {
private final Supplier<Participant> activeParticipantCallback; private final Supplier<EntityID> getActiveCharacterCallback;
/** /**
* Creates a new {@link FilterEndRoundRequestSegment} * Creates a new {@link FilterEndRoundRequestSegment}
* @param activeParticipantCallback is a {@link Supplier}<{@link Participant}> * @param getActiveCharacterCallback is a {@link Supplier}<{@link Participant}>
* that supplies the currently active participant * that supplies the currently active participant
* in a {@link Lobby}. It should normally be bound * in a {@link Lobby}. It should normally be bound
* to {@link Lobby#getActivePlayer()}, by executing * to {@link GameStateView#getActiveCharacter()}, by executing
* {@code new Filter...Segment(this::getActivePlayer)}. * {@code new Filter...Segment(game.state::getActiveCharacter)}.
*/ */
public FilterEndRoundRequestSegment(Supplier<Participant> activeParticipantCallback) { public FilterEndRoundRequestSegment(Supplier<EntityID> getActiveCharacterCallback) {
this.activeParticipantCallback = activeParticipantCallback; this.getActiveCharacterCallback = getActiveCharacterCallback;
} }
@ -37,8 +41,12 @@ public class FilterEndRoundRequestSegment implements Segment {
Logger.trace("FilterEndRoundSegment has received {} requests", packet.size()); Logger.trace("FilterEndRoundSegment has received {} requests", packet.size());
if (packet.containsRequestOfType(RequestType.EndRoundRequest)) { if (packet.containsRequestOfType(RequestType.EndRoundRequest)) {
Logger.trace("Packet contains EndRoundRequest"); Logger.trace("Packet contains EndRoundRequest");
if (!packet.getOrigin().equals(activeParticipantCallback.get())) {
Logger.debug("Packet contained EndRoundRequest but was sent from non-active participant, aborting..."); var active = getActiveCharacterCallback.get().type;
var from = packet.getOrigin().type == ParticipantType.PlayerOne ? EntityType.P1 : EntityType.P2;
if (packet.containsRequestOfType(RequestType.EndRoundRequest) && active != from) {
Logger.trace("Invalid endRoundRequest. Expected {} but got {}. Aborting...", active, from);
abort.set(true); abort.set(true);
} }
} }

View File

@ -1,36 +0,0 @@
package uulm.teamname.marvelous.server.lobby.pipelining;
import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.entities.EntityType;
import uulm.teamname.marvelous.gamelibrary.events.Event;
import uulm.teamname.marvelous.gamelibrary.gamelogic.GameInstance;
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
import uulm.teamname.marvelous.gamelibrary.messages.server.EventMessage;
import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* The {@link RequestTurnEndSegment} handles requests of {@link RequestType} EndRoundRequest. It filters invalid turn end requests.
*/
public class RequestTurnEndSegment implements Segment {
private final GameInstance game;
public RequestTurnEndSegment(GameInstance game) {
this.game = game;
}
@Override
public void processRequests(Packet packet, List<Event> carrier, AtomicBoolean abort) {
Logger.trace("RequestTurnEndSegment received {} requests", packet.size());
var active = game.state.getActiveCharacter().type;
var from = packet.getOrigin().type == ParticipantType.PlayerOne ? EntityType.P1 : EntityType.P2;
if (packet.containsRequestOfType(RequestType.EndRoundRequest) && active != from) {
Logger.trace("Invalid end turn request. Aborting");
abort.set(true);
}
}
}

View File

@ -3,10 +3,14 @@ package uulm.teamname.marvelous.server.lobby.pipelining;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
import uulm.teamname.marvelous.gamelibrary.entities.EntityType;
import uulm.teamname.marvelous.gamelibrary.messages.ParticipantType;
import uulm.teamname.marvelous.gamelibrary.requests.Request; import uulm.teamname.marvelous.gamelibrary.requests.Request;
import uulm.teamname.marvelous.gamelibrary.requests.RequestBuilder; import uulm.teamname.marvelous.gamelibrary.requests.RequestBuilder;
import uulm.teamname.marvelous.gamelibrary.requests.RequestType; import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
import uulm.teamname.marvelous.server.lobbymanager.Participant; import uulm.teamname.marvelous.server.lobbymanager.Participant;
import uulm.teamname.marvelous.server.netconnector.Client;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -18,21 +22,27 @@ class FilterEndRoundRequestSegmentTest {
FilterEndRoundRequestSegment segment; FilterEndRoundRequestSegment segment;
Participant activeParticipant; EntityID activeCharacter;
Participant activeParticipant, inactiveParticipant;
Request[] requests; Request[] requests;
@BeforeEach @BeforeEach
void beforeEach() { void beforeEach() {
this.segment = new FilterEndRoundRequestSegment(this::getActiveParticipant); this.segment = new FilterEndRoundRequestSegment(this::getActiveCharacter);
this.activeParticipant = mock(Participant.class);
this.activeCharacter = new EntityID(EntityType.P1, 2);
this.activeParticipant = new Participant(mock(Client.class), null, ParticipantType.PlayerOne, false);
this.inactiveParticipant = new Participant(mock(Client.class), null, ParticipantType.PlayerTwo, false);
requests = new Request[] { requests = new Request[] {
new RequestBuilder(RequestType.EndRoundRequest).buildGameRequest() new RequestBuilder(RequestType.EndRoundRequest).buildGameRequest()
}; };
} }
private Participant getActiveParticipant() { private EntityID getActiveCharacter() {
return activeParticipant; return activeCharacter;
} }
@Test @Test
@ -51,7 +61,7 @@ class FilterEndRoundRequestSegmentTest {
@Test @Test
@DisplayName("Request from non-active participant gets flagged as an error") @DisplayName("Request from non-active participant gets flagged as an error")
void packetFromNonActiveParticipantTest() { void packetFromNonActiveParticipantTest() {
var packet = new Packet(requests, mock(Participant.class)); var packet = new Packet(requests, inactiveParticipant);
var atomicBoolean = new AtomicBoolean(false); var atomicBoolean = new AtomicBoolean(false);
var processedPacket = (Packet) packet.clone(); var processedPacket = (Packet) packet.clone();