From a75d7b8d87244cd6ec8239152002d124446a337e Mon Sep 17 00:00:00 2001 From: Martijn Date: Thu, 5 Oct 2017 22:59:40 +0200 Subject: [PATCH 1/5] You will receive a message when the game is won. I also cleaned up all the other messages and some other classes on the way --- .../common/protocol/CollisionMessage.java | 45 +---- .../common/protocol/DamageMessage.java | 29 +-- .../common/protocol/FireBulletMessage.java | 21 +-- .../common/protocol/GameFinishedMessage.java | 18 ++ .../common/protocol/KillMessage.java | 29 +-- .../common/protocol/MovementMessage.java | 18 +- ...RequestArchitectureStateChangeMessage.java | 20 +- .../common/protocol/StateMessage.java | 80 ++++---- .../common/protocol/TextMessage.java | 17 +- .../common/gameevent/CollisionStartEvent.java | 4 +- .../common/gameevent/DestroyBulletEvent.java | 2 +- .../common/gameevent/DestroyEvent.java | 4 + .../gameevent/DestroyHealthEntityEvent.java | 2 +- .../common/gameevent/GameFinishedEvent.java | 19 ++ .../gameengine/GameEngine.java | 54 ++++-- .../ruleprocessors/RuleProcessors.java | 49 +++-- .../gameengine/ruleprocessors/RuleSets.java | 2 + .../rules/AbstractGameFinishedRule.java | 33 ++++ .../deathmatch/DeathmatchGameFinished.java | 27 +++ .../rules/teamplay/TeamplayGameFinished.java | 30 +++ .../subscriber/RabbitMessageConsumer.java | 4 +- .../rabbitmq/subscriber/RabbitSubscriber.java | 3 +- .../dronessimulator/visualisation/Game.java | 171 +++++++++--------- .../messagehandlers/GameFinishedHandler.java | 48 +++++ 24 files changed, 411 insertions(+), 318 deletions(-) create mode 100644 implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/GameFinishedMessage.java create mode 100644 implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyEvent.java create mode 100644 implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java create mode 100644 implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java create mode 100644 implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java create mode 100644 implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java create mode 100644 implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/CollisionMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/CollisionMessage.java index e74dba14..f199599c 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/CollisionMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/CollisionMessage.java @@ -1,12 +1,17 @@ package org.inaetics.dronessimulator.common.protocol; -import java.util.ArrayList; +import lombok.Getter; +import lombok.Setter; + +import java.util.Collections; import java.util.List; /** * A message describing a collision between 2 entities */ +@Getter +@Setter public class CollisionMessage extends ProtocolMessage { /** * The type of the first entity @@ -26,38 +31,6 @@ public class CollisionMessage extends ProtocolMessage { */ private String e2Identifier; - public EntityType getE1Type() { - return e1Type; - } - - public void setE1Type(EntityType e1Type) { - this.e1Type = e1Type; - } - - public String getE1Id() { - return e1Identifier; - } - - public void setE1Id(String e1Id) { - this.e1Identifier = e1Id; - } - - public EntityType getE2Type() { - return e2Type; - } - - public void setE2Type(EntityType e2Type) { - this.e2Type = e2Type; - } - - public String getE2Id() { - return e2Identifier; - } - - public void setE2Id(String e2Id) { - this.e2Identifier = e2Id; - } - @Override public String toString() { return String.format("(CollisionMessage %s %s, %s, %s)", this.e1Identifier, this.e1Type, this.e2Identifier, this.e2Type); @@ -65,10 +38,6 @@ public String toString() { @Override public List getTopics() { - List topics = new ArrayList<>(); - - topics.add(MessageTopic.STATEUPDATES); - - return topics; + return Collections.singletonList(MessageTopic.STATEUPDATES); } } diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/DamageMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/DamageMessage.java index 497bc504..1c745640 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/DamageMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/DamageMessage.java @@ -1,11 +1,16 @@ package org.inaetics.dronessimulator.common.protocol; +import lombok.Getter; +import lombok.Setter; + import java.util.Collections; import java.util.List; /** * Protocol message describing that an entity has been damaged */ +@Getter +@Setter public class DamageMessage extends ProtocolMessage { /** * The id of the entity which is damaged @@ -21,30 +26,6 @@ public class DamageMessage extends ProtocolMessage { */ private int damage; - public String getEntityId() { - return entityId; - } - - public void setEntityId(String entityId) { - this.entityId = entityId; - } - - public EntityType getEntityType() { - return entityType; - } - - public void setEntityType(EntityType entityType) { - this.entityType = entityType; - } - - public int getDamage() { - return damage; - } - - public void setDamage(int damage) { - this.damage = damage; - } - @Override public List getTopics() { return Collections.singletonList(MessageTopic.STATEUPDATES); diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/FireBulletMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/FireBulletMessage.java index e6323119..12efa807 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/FireBulletMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/FireBulletMessage.java @@ -1,8 +1,13 @@ package org.inaetics.dronessimulator.common.protocol; +import lombok.Getter; +import lombok.Setter; + /** * Message specifying a bullet is fired */ +@Getter +@Setter public class FireBulletMessage extends CreateEntityMessage { /** * The damage of the bullet @@ -13,22 +18,6 @@ public class FireBulletMessage extends CreateEntityMessage { */ private String firedById; - public int getDamage() { - return damage; - } - - public void setDamage(int damage) { - this.damage = damage; - } - - public String getFiredById() { - return firedById; - } - - public void setFiredById(String firedById) { - this.firedById = firedById; - } - public String toString() { return String.format("(FireBulletMessage %s fired by %s, %s)", this.getIdentifier(), this.getFiredById(), this.getDamage()); } diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/GameFinishedMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/GameFinishedMessage.java new file mode 100644 index 00000000..d827d1cf --- /dev/null +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/GameFinishedMessage.java @@ -0,0 +1,18 @@ +package org.inaetics.dronessimulator.common.protocol; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Collections; +import java.util.List; + +@RequiredArgsConstructor +public class GameFinishedMessage extends ProtocolMessage { + @Getter + private final String winner; + + @Override + public List getTopics() { + return Collections.singletonList(MessageTopic.STATEUPDATES); + } +} diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/KillMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/KillMessage.java index efe226c1..922926f9 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/KillMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/KillMessage.java @@ -1,37 +1,22 @@ package org.inaetics.dronessimulator.common.protocol; -import java.util.ArrayList; +import lombok.Getter; +import lombok.Setter; + +import java.util.Collections; import java.util.List; +@Getter +@Setter public class KillMessage extends ProtocolMessage { /** Indentifier of object */ private String identifier = null; private EntityType entityType; - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } - - public EntityType getEntityType() { - return entityType; - } - - public void setEntityType(EntityType entityType) { - this.entityType = entityType; - } - @Override public List getTopics() { - List topics = new ArrayList<>(); - - topics.add(MessageTopic.STATEUPDATES); - - return topics; + return Collections.singletonList(MessageTopic.STATEUPDATES); } @Override diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/MovementMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/MovementMessage.java index 26e38c74..0c00a13b 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/MovementMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/MovementMessage.java @@ -1,5 +1,7 @@ package org.inaetics.dronessimulator.common.protocol; +import lombok.Getter; +import lombok.Setter; import org.inaetics.dronessimulator.common.vector.D3PolarCoordinate; import org.inaetics.dronessimulator.common.vector.D3Vector; @@ -10,6 +12,8 @@ /** * Message used to tell the game state about movements. */ +@Getter +@Setter public class MovementMessage extends ProtocolMessage { /** Indentifier of object */ private String identifier = null; @@ -24,24 +28,10 @@ public Optional getDirection() { return Optional.ofNullable(direction); } - public void setDirection(D3PolarCoordinate direction) { - this.direction = direction; - } - public Optional getAcceleration() { return Optional.ofNullable(acceleration); } - public void setAcceleration(D3Vector acceleration) { - this.acceleration = acceleration; - } - - public String getIdentifier() { - return this.identifier; - } - - public void setIdentifier(String identifier){ this.identifier = identifier; } - @Override public List getTopics() { List topics = new ArrayList<>(); diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/RequestArchitectureStateChangeMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/RequestArchitectureStateChangeMessage.java index 7cbfcee3..7ff3e90e 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/RequestArchitectureStateChangeMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/RequestArchitectureStateChangeMessage.java @@ -1,6 +1,8 @@ package org.inaetics.dronessimulator.common.protocol; +import lombok.Getter; +import lombok.Setter; import org.inaetics.dronessimulator.common.architecture.SimulationAction; import java.util.Collections; @@ -9,6 +11,8 @@ /** * A message to request a architecture state change */ +@Getter +@Setter public class RequestArchitectureStateChangeMessage extends ProtocolMessage { /** * The action to take @@ -20,22 +24,6 @@ public List getTopics() { return Collections.singletonList(MessageTopic.ARCHITECTURE); } - /** - * Gets the requested action to take - * @return The action - */ - public SimulationAction getAction() { - return action; - } - - /** - * Set the requested action in the message - * @param action Which action to request - */ - public void setAction(SimulationAction action) { - this.action = action; - } - @Override public String toString() { return "RequestArchitectureStateChangeMessage " + action; diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/StateMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/StateMessage.java index f1e8b576..f774b1d7 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/StateMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/StateMessage.java @@ -1,9 +1,11 @@ package org.inaetics.dronessimulator.common.protocol; +import lombok.Getter; +import lombok.Setter; import org.inaetics.dronessimulator.common.vector.D3PolarCoordinate; import org.inaetics.dronessimulator.common.vector.D3Vector; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; @@ -11,79 +13,70 @@ * Message used by the game state to communicate state changes to other nodes. */ public class StateMessage extends ProtocolMessage { - /** Indentifier of object */ + /** + * Indentifier of object + */ + @Getter + @Setter private String identifier = null; - /** Type of the object */ + /** + * Type of the object + */ + @Getter + @Setter private EntityType type; - /** The position of the object. */ + /** + * The position of the object. + */ + @Setter private D3Vector position = null; - /** The direction the object is in. */ + /** + * The direction the object is in. + */ + @Setter private D3PolarCoordinate direction = null; - /** The velocity of the object. */ + /** + * The velocity of the object. + */ + @Setter private D3Vector velocity = null; - /** The acceleration of the object. */ + /** + * The acceleration of the object. + */ + @Setter private D3Vector acceleration = null; + @Setter private Integer hp = null; public Optional getPosition() { return Optional.ofNullable(position); } - public void setPosition(D3Vector position) { - this.position = position; - } - public Optional getDirection() { return Optional.ofNullable(direction); } - public void setDirection(D3PolarCoordinate direction) { - this.direction = direction; - } - public Optional getVelocity() { return Optional.ofNullable(velocity); } - public void setVelocity(D3Vector velocity) { - this.velocity = velocity; - } - public Optional getAcceleration() { return Optional.ofNullable(acceleration); } - public void setAcceleration(D3Vector acceleration) { - this.acceleration = acceleration; - } - - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier){ this.identifier = identifier; } - - public EntityType getType() { - return type; - } - - public void setType(EntityType type) { - this.type = type; + public Optional getHp() { + return Optional.ofNullable(hp); } @Override public List getTopics() { - List topics = new ArrayList<>(); - - topics.add(MessageTopic.STATEUPDATES); - - return topics; + return Collections.singletonList(MessageTopic.STATEUPDATES); } @Override @@ -91,11 +84,4 @@ public String toString() { return String.format("(StateMessage %s %s, %s, %s, %s, %s)", this.identifier, this.position, this.direction, this.velocity, this.acceleration, this.hp); } - public Optional getHp() { - return Optional.ofNullable(hp); - } - - public void setHp(int hp) { - this.hp = hp; - } } diff --git a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/TextMessage.java b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/TextMessage.java index b10019e5..5cbb11d7 100644 --- a/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/TextMessage.java +++ b/implementation/common/src/main/java/org/inaetics/dronessimulator/common/protocol/TextMessage.java @@ -1,24 +1,23 @@ package org.inaetics.dronessimulator.common.protocol; +import lombok.Getter; +import lombok.Setter; + import java.util.ArrayList; import java.util.List; /** * Message used by radio component for text communication between components. */ +@Getter +@Setter public class TextMessage extends ProtocolMessage { - /** the actual message */ + /** + * the actual message + */ private String text = null; - public String getText() { - return this.text; - } - - public void setText(String text) { - this.text = text; - } - @Override public List getTopics() { List topics = new ArrayList<>(); diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/CollisionStartEvent.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/CollisionStartEvent.java index 24c1efa2..97abfda9 100644 --- a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/CollisionStartEvent.java +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/CollisionStartEvent.java @@ -31,10 +31,10 @@ public List getProtocolMessage(IdentifierMapper id_mapper) { Optional maybeE2 = id_mapper.fromGameEngineToProtocolId(this.e2.getEntityId()); if(maybeE1.isPresent() && maybeE2.isPresent()) { - msg.setE1Id(maybeE1.get()); + msg.setE1Identifier(maybeE1.get()); msg.setE1Type(this.e1.getType()); - msg.setE2Id(maybeE2.get()); + msg.setE2Identifier(maybeE2.get()); msg.setE2Type(this.e2.getType()); return Collections.singletonList(msg); diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyBulletEvent.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyBulletEvent.java index 90016d27..869161d0 100644 --- a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyBulletEvent.java +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyBulletEvent.java @@ -18,7 +18,7 @@ @AllArgsConstructor @Getter @ToString -public class DestroyBulletEvent extends GameEngineEvent { +public class DestroyBulletEvent extends DestroyEvent { /** The id of the bullet. */ private final int id; diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyEvent.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyEvent.java new file mode 100644 index 00000000..5496c6da --- /dev/null +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyEvent.java @@ -0,0 +1,4 @@ +package org.inaetics.dronessimulator.gameengine.common.gameevent; + +public abstract class DestroyEvent extends GameEngineEvent { +} diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyHealthEntityEvent.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyHealthEntityEvent.java index 6c80b42b..277e0d71 100644 --- a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyHealthEntityEvent.java +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/DestroyHealthEntityEvent.java @@ -18,7 +18,7 @@ @AllArgsConstructor @Getter @ToString -public class DestroyHealthEntityEvent extends GameEngineEvent { +public class DestroyHealthEntityEvent extends DestroyEvent { /** The game entity that got destroyed. */ private final HealthGameEntity destroyedEntity; diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java new file mode 100644 index 00000000..e1530421 --- /dev/null +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java @@ -0,0 +1,19 @@ +package org.inaetics.dronessimulator.gameengine.common.gameevent; + +import lombok.RequiredArgsConstructor; +import org.inaetics.dronessimulator.common.protocol.GameFinishedMessage; +import org.inaetics.dronessimulator.common.protocol.ProtocolMessage; +import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; + +import java.util.Collections; +import java.util.List; + +@RequiredArgsConstructor +public class GameFinishedEvent extends GameEngineEvent { + private final String winner; + + @Override + public List getProtocolMessage(IdentifierMapper id_mapper) { + return Collections.singletonList(new GameFinishedMessage(winner)); + } +} diff --git a/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java b/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java index db451a40..4a7d32cb 100644 --- a/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java +++ b/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java @@ -14,7 +14,6 @@ import org.inaetics.dronessimulator.discovery.api.DuplicateName; import org.inaetics.dronessimulator.discovery.api.Instance; import org.inaetics.dronessimulator.discovery.api.discoverynode.DiscoveryNode; -import org.inaetics.dronessimulator.discovery.api.discoverynode.Group; import org.inaetics.dronessimulator.discovery.api.discoverynode.NodeEventHandler; import org.inaetics.dronessimulator.discovery.api.discoverynode.Type; import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.AddedNode; @@ -31,7 +30,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; /** @@ -45,29 +43,43 @@ public class GameEngine { */ private final static Logger logger = Logger.getLogger(GameEngine.class); - /** Physics engine used in the game engine. */ + /** + * Physics engine used in the game engine. + */ private volatile IPhysicsEngineDriver m_physicsEngineDriver; - /** Manager of state outside of physicsengine. */ + /** + * Manager of state outside of physicsengine. + */ private volatile IGameStateManager m_stateManager; - /** Rule processors to handle any outgoing messages. The last rule processor SendMessages sends all messages off. */ + /** + * Rule processors to handle any outgoing messages. The last rule processor SendMessages sends all messages off. + */ private volatile IRuleProcessors m_ruleProcessors; - /** The subscriber to use. */ + /** + * The subscriber to use. + */ private volatile Subscriber m_subscriber; - /** The identifier mapper to use. */ + /** + * The identifier mapper to use. + */ private volatile IdentifierMapper m_id_mapper; - /** The discoverer to use. */ + /** + * The discoverer to use. + */ private volatile Discoverer m_discoverer; private volatile ArchitectureEventController m_architectureEventListener; private List lobbiedDrones = new ArrayList<>(); - /** Concrete message handlers. */ + /** + * Concrete message handlers. + */ private CollisionMessageHandler collisionMessageHandler; private DamageMessageHandler damageMessageHandler; private FireBulletMessageHandler fireBulletMessageHandler; @@ -75,7 +87,9 @@ public class GameEngine { private MovementMessageHandler movementMessageHandler; private StateMessageHandler stateMessageHandler; - /** The game engine instance to register. */ + /** + * The game engine instance to register. + */ private Instance discoveryInstance; /** @@ -93,10 +107,14 @@ public void start() throws DuplicateName, IOException { // Setup subscriber try { this.m_subscriber.addTopic(MessageTopic.MOVEMENTS); - this.m_subscriber.addTopic(MessageTopic.STATEUPDATES); - } catch(IOException e) { + } catch (IOException e) { logger.fatal("Could not subscribe to topic " + MessageTopic.MOVEMENTS + ".", e); } + try { + this.m_subscriber.addTopic(MessageTopic.STATEUPDATES); + } catch (IOException e) { + logger.fatal("Could not subscribe to topic " + MessageTopic.STATEUPDATES + ".", e); + } this.m_subscriber.addHandler(CollisionMessage.class, this.collisionMessageHandler); this.m_subscriber.addHandler(DamageMessage.class, this.damageMessageHandler); @@ -115,7 +133,7 @@ public void start() throws DuplicateName, IOException { DiscoveryNode node = addedNodeEvent.getNode(); DiscoveryPath path = node.getPath(); - if( path.startsWith(DiscoveryPath.type(Type.DRONE)) && path.isConfigPath()) { + if (path.startsWith(DiscoveryPath.type(Type.DRONE)) && path.isConfigPath()) { lobbiedDrones.add(node.getId()); logger.info("Added new drone " + node.getId() + " in simulation/lobby"); @@ -129,7 +147,7 @@ public void start() throws DuplicateName, IOException { DiscoveryNode node = removedNodeEvent.getNode(); DiscoveryPath path = node.getPath(); - if( path.startsWith(DiscoveryPath.type(Type.DRONE)) && path.isConfigPath()) { + if (path.startsWith(DiscoveryPath.type(Type.DRONE)) && path.isConfigPath()) { String protocolId = node.getId(); lobbiedDrones.remove(protocolId); @@ -149,11 +167,11 @@ public void start() throws DuplicateName, IOException { double spawnAngle = (2 * Math.PI) / dronesInLobby; int numberSpawned = 0; - for(String protocolId : lobbiedDrones) { + for (String protocolId : lobbiedDrones) { int gameengineId = m_id_mapper.getNewGameEngineId(); - D3Vector position = new D3Vector( Math.cos(spawnAngle * numberSpawned) * spawnRadius + center.getX() - , Math.sin(spawnAngle * numberSpawned) * spawnRadius + center.getY() - , 50); + D3Vector position = new D3Vector(Math.cos(spawnAngle * numberSpawned) * spawnRadius + center.getX() + , Math.sin(spawnAngle * numberSpawned) * spawnRadius + center.getY() + , 50); numberSpawned++; this.m_physicsEngineDriver.addNewEntity(new Drone(gameengineId, Drone.DRONE_MAX_HEALTH, position, new D3Vector(), new D3Vector(), new D3PolarCoordinate()), protocolId); diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java index 5d16ef4e..e00a42b2 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java @@ -3,7 +3,6 @@ import org.apache.log4j.Logger; import org.inaetics.dronessimulator.architectureevents.ArchitectureEventController; -import org.inaetics.dronessimulator.common.GameMode; import org.inaetics.dronessimulator.common.Settings; import org.inaetics.dronessimulator.common.architecture.SimulationAction; import org.inaetics.dronessimulator.common.architecture.SimulationState; @@ -17,32 +16,42 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; -import java.util.stream.Collectors; /** * Rule processors service. The rule processors listen on events and act on them based on predefined rules. */ public class RuleProcessors extends Thread implements IRuleProcessors { + private final Logger logger = Logger.getLogger(RuleProcessors.class); private ArchitectureEventController m_architectureEventController; - /** The physics engine driver to get events from. */ + /** + * The physics engine driver to get events from. + */ private IPhysicsEngineDriver m_driver; - /** The publisher to send messages to. */ + /** + * The publisher to send messages to. + */ private Publisher m_publisher; - /** The identifier mapper. */ + /** + * The identifier mapper. + */ private IdentifierMapper m_id_mapper; - /** Queue of the events to process. */ + /** + * Queue of the events to process. + */ private LinkedBlockingQueue incomingEvents; - /** Active rules. Should end SendMessages to broadcast the messages to other subsystems. */ + /** + * Active rules. Should end SendMessages to broadcast the messages to other subsystems. + */ private Rule[] rules; @Override public void start() { - Logger.getLogger(RuleProcessors.class).info("Starting Rule Processors..."); + logger.info("Starting Rule Processors..."); assert m_driver != null; @@ -61,48 +70,50 @@ public void start() { @Override public void run() { - Logger.getLogger(RuleProcessors.class).info("Started RuleProcessors"); - while(!this.isInterrupted()) { + logger.info("Started RuleProcessors"); + while (!this.isInterrupted()) { GameEngineEvent msg; try { msg = incomingEvents.take(); } catch (InterruptedException e) { - Logger.getLogger(RuleProcessors.class).error("Interrupted while waiting for incoming event"); + logger.error("Interrupted while waiting for incoming event"); this.interrupt(); break; } - if(msg != null) { + if (msg != null) { this.processEventsForRules(Collections.singletonList(msg)); } else { - Logger.getLogger(RuleProcessors.class).error("Received event on incoming queue but was null!"); + logger.error("Received event on incoming queue but was null!"); } } - Logger.getLogger(RuleProcessors.class).info("Ruleprocessors is shut down!"); + logger.info("Ruleprocessors is shut down!"); } /** * Processes the given events in each of the defined rules, in order. + * * @param events The events to process. */ public void processEventsForRules(List events) { List allEvents = events; - for(Rule rule : this.rules) { + for (Rule rule : this.rules) { allEvents = this.processEventsForRule(allEvents, rule); } } /** * Processes the given events for the given rule. + * * @param events The events to process. - * @param rule The rule to apply. + * @param rule The rule to apply. * @return The list of events to pass to the next rule. */ public List processEventsForRule(List events, Rule rule) { List result = new ArrayList<>(events.size() * 2); - for(GameEngineEvent event : events) { + for (GameEngineEvent event : events) { result.addAll(rule.process(event)); } @@ -110,7 +121,7 @@ public List processEventsForRule(List events, } public void configRules() { - for(Rule rule : rules) { + for (Rule rule : rules) { rule.configRule(); } } @@ -119,7 +130,7 @@ public void configRules() { * Stops the rule processors. */ public void quit() { - Logger.getLogger(RuleProcessors.class).info("Shutting down ruleprocessors..."); + logger.info("Shutting down ruleprocessors..."); this.interrupt(); } diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java index 5e1f4490..1def0bb3 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java @@ -5,6 +5,7 @@ import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.*; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch.CollisionRule; +import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch.DeathmatchGameFinished; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch.KillEntitiesRule; import org.inaetics.dronessimulator.pubsub.api.publisher.Publisher; @@ -19,6 +20,7 @@ public static Rule[] getRulesForGameMode(GameMode gameMode, Publisher publisher, , new KillEntitiesRule() , new RemoveStrayBullets() , new RemoveStaleStateData() + , new DeathmatchGameFinished() , new SendMessages(publisher, idMapper) }; break; diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java new file mode 100644 index 00000000..13bce02b --- /dev/null +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java @@ -0,0 +1,33 @@ +package org.inaetics.dronessimulator.gameengine.ruleprocessors.rules; + +import org.inaetics.dronessimulator.gameengine.common.gameevent.CurrentStateEvent; +import org.inaetics.dronessimulator.gameengine.common.gameevent.GameEngineEvent; +import org.inaetics.dronessimulator.gameengine.common.gameevent.GameFinishedEvent; +import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; + +import java.util.Collections; +import java.util.List; + +public abstract class AbstractGameFinishedRule extends Rule { + @Override + public void configRule() { + //no config + } + + @Override + public List process(GameEngineEvent msg) { + if (msg instanceof CurrentStateEvent) { + CurrentStateEvent currentStateEvent = (CurrentStateEvent) msg; + if (gameIsFinished(currentStateEvent.getCurrentState())) { + return Collections.singletonList(new GameFinishedEvent(getWinner())); + } + } + return Collections.singletonList(msg); + + + } + + protected abstract String getWinner(); + + protected abstract boolean gameIsFinished(List currentState); +} diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java new file mode 100644 index 00000000..79de68fb --- /dev/null +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java @@ -0,0 +1,27 @@ +package org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch; + +import org.inaetics.dronessimulator.common.protocol.EntityType; +import org.inaetics.dronessimulator.gameengine.common.state.Drone; +import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; +import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.AbstractGameFinishedRule; + +import java.util.List; + +public class DeathmatchGameFinished extends AbstractGameFinishedRule { + private int winner; + + @Override + protected String getWinner() { + return String.valueOf(winner); + } + + @Override + protected boolean gameIsFinished(List currentState) { + final int[] count = {0}; //One element array to avoid the final constraint by lambdas + currentState.stream().filter(gameEntity -> EntityType.DRONE.equals(gameEntity.getType())).map(gameEntity -> ((Drone) gameEntity)).filter(drone -> drone.getHp() > 0).forEach(drone -> { + count[0]++; + winner = drone.getEntityId(); + }); + return count[0] == 1; + } +} diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java new file mode 100644 index 00000000..1635e694 --- /dev/null +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java @@ -0,0 +1,30 @@ +package org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.teamplay; + +import org.inaetics.dronessimulator.common.protocol.EntityType; +import org.inaetics.dronessimulator.gameengine.common.state.Drone; +import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; +import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.AbstractGameFinishedRule; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class TeamplayGameFinished extends AbstractGameFinishedRule { + private Map dronesPerTeam; + + @Override + protected boolean gameIsFinished(List currentState) { + dronesPerTeam = currentState.stream().filter(gameEntity -> EntityType.DRONE.equals(gameEntity.getType())).map(gameEntity -> ((Drone) gameEntity)) + .filter(drone -> drone.getHp() > 0).collect(Collectors.groupingBy( + drone -> { + return String.valueOf(drone.getEntityId()); //todo replace with teamname + }, Collectors.counting() + )); + return dronesPerTeam.size() == 1; + } + + @Override + protected String getWinner() { + return dronesPerTeam.keySet().iterator().next(); + } +} diff --git a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitMessageConsumer.java b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitMessageConsumer.java index 058e75b8..b9c72cf0 100644 --- a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitMessageConsumer.java +++ b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitMessageConsumer.java @@ -32,11 +32,11 @@ public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProp if (serializer != null) { try { Message message = serializer.deserialize(body); - this.getChannel().basicAck(envelope.getDeliveryTag(), false); + if (getChannel().isOpen()) this.getChannel().basicAck(envelope.getDeliveryTag(), false); subscriber.receive(message); } catch (ClassNotFoundException e) { // Reject the message since we cannot do anything useful with it - this.getChannel().basicNack(envelope.getDeliveryTag(), false, false); + if (getChannel().isOpen()) this.getChannel().basicNack(envelope.getDeliveryTag(), false, false); subscriber.getLogger().warn("Received message of unknown type, message dropped", e); } } diff --git a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java index 37869e8b..5e3f24bd 100644 --- a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java +++ b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java @@ -208,7 +208,8 @@ public void updateConsumer() throws IOException { logger.debug("New RabbitMQ consumer started"); // Cancel old consumer if we have one - if (old != null) { + if (old != null && old.getConsumerTag() != null) { + logger.debug("Cancel old RabbitMQ consumer with tag: " + old.getConsumerTag()); this.channel.basicCancel(old.getConsumerTag()); logger.debug("Old RabbitMQ consumer cancelled"); } diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java index 4db6be35..8cae3e36 100644 --- a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java @@ -28,10 +28,11 @@ import org.inaetics.dronessimulator.discovery.api.discoverynode.NodeEventHandler; import org.inaetics.dronessimulator.discovery.api.discoverynode.Type; import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.AddedNode; -import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.ChangedValue; +import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.NodeEvent; import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.RemovedNode; import org.inaetics.dronessimulator.discovery.etcd.EtcdDiscovererService; import org.inaetics.dronessimulator.pubsub.javaserializer.JavaSerializer; +import org.inaetics.dronessimulator.pubsub.rabbitmq.common.RabbitConnectionInfo; import org.inaetics.dronessimulator.pubsub.rabbitmq.publisher.RabbitPublisher; import org.inaetics.dronessimulator.pubsub.rabbitmq.subscriber.RabbitSubscriber; import org.inaetics.dronessimulator.visualisation.controls.PannableCanvas; @@ -40,9 +41,6 @@ import org.inaetics.dronessimulator.visualisation.uiupdates.UIUpdate; import java.io.IOException; -import java.net.URISyntaxException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; @@ -55,34 +53,34 @@ * contain all the game elements. */ public class Game extends Application { - /** - * Subscriber for rabbitmq - */ - private RabbitSubscriber subscriber; - /** - * Publisher for rabbitmq - */ - private RabbitPublisher publisher; - /** - * Discoverer for etcd - */ - private EtcdDiscovererService discoverer; - /** * Logger */ private static final Logger logger = Logger.getLogger(Game.class); - /** * All the entities in the game */ private final ConcurrentMap entities = new ConcurrentHashMap<>(); - /** * Rabbitmq configuration */ private final Map rabbitConfig = new HashMap<>(); - + /** + * UI updates + */ + private final BlockingQueue uiUpdates; + /** + * Subscriber for rabbitmq + */ + private RabbitSubscriber subscriber; + /** + * Publisher for rabbitmq + */ + private RabbitPublisher publisher; + /** + * Discoverer for etcd + */ + private EtcdDiscovererService discoverer; /** * The pannable and zommable canvas */ @@ -91,23 +89,11 @@ public class Game extends Application { * Group for all entities */ private Group root; - - /** - * UI updates - */ - private final BlockingQueue uiUpdates; /** * check to see if the method onRabbitConnect is executed */ private AtomicBoolean onRabbitConnectExecuted = new AtomicBoolean(false); - - /** - * Instantiates a new game object - */ - public Game() { - this.uiUpdates = new LinkedBlockingQueue<>(); - } - + private Stage primaryStage; /** * counter for the logger to output once every 100 times */ @@ -116,7 +102,6 @@ public Game() { * Time is ms of the last log */ private long lastLog = -1; - /** * Close event handler * When the window closes, rabbitmq and the discoverer disconnect @@ -143,6 +128,24 @@ public void handle(WindowEvent t) { } } }; + private RabbitConnectionInfo rabbitConnectionInfo; + private GameFinishedHandler gameFinishedHandler; + + /** + * Instantiates a new game object + */ + public Game() { + this.uiUpdates = new LinkedBlockingQueue<>(); + } + + /** + * Main method of the visualisation + * + * @param args - args + */ + public static void main(String[] args) { + launch(args); + } /** * Main entry point for a JavaFX application @@ -151,7 +154,8 @@ public void handle(WindowEvent t) { */ @Override public void start(Stage primaryStage) { - setupInterface(primaryStage); + this.primaryStage = primaryStage; + setupInterface(); setupDiscovery(); setupRabbit(); setupGameEventListener(); @@ -164,9 +168,15 @@ public void handle(long now) { long current_step_started_at_ms = System.currentTimeMillis(); if (!isRabbitConnected()) { - logger.info("RabbitMQ is not (yet) connected."); - } - else if (!onRabbitConnectExecuted.get()) { + logger.info("RabbitMQ is not (yet) connected. " + + "subscriber != null == " + (subscriber != null) + " subscriber.isConnected() == " + (subscriber != null && subscriber.isConnected()) + " " + + "publisher != null == " + (publisher != null) + " publisher.isConnected() == " + (publisher != null && publisher.isConnected())); + try { + connectRabbit(); + } catch (IOException e) { + logger.fatal(e); + } + } else if (!onRabbitConnectExecuted.get()) { onRabbitConnect(); onRabbitConnectExecuted.set(true); } @@ -273,61 +283,58 @@ private void setupGameEventListener() { * Sets up the connection to the message broker and subscribes to the necessary channels and sets the required handlers */ private void setupRabbit() { - List> changedValueHandlers = new ArrayList<>(); + this.discoverer.addHandlers(true, Collections.singletonList(this::handleNodeEvent), Collections.singletonList(this::handleNodeEvent), Collections.emptyList()); + } - changedValueHandlers.add((ChangedValue e) -> { - DiscoveryNode node = e.getNode(); - DiscoveryPath path = node.getPath(); + private void handleNodeEvent(NodeEvent e) { + DiscoveryNode node = e.getNode(); + DiscoveryPath path = node.getPath(); - if (path.equals(DiscoveryPath.config(Type.RABBITMQ, org.inaetics.dronessimulator.discovery.api.discoverynode.Group.BROKER, "default"))) { - if (node.getValue("username") != null) { - rabbitConfig.put("username", node.getValue("username")); - } + if (path.equals(DiscoveryPath.config(Type.RABBITMQ, org.inaetics.dronessimulator.discovery.api.discoverynode.Group.BROKER, "default"))) { + if (node.getValue("username") != null) { + rabbitConfig.put("username", node.getValue("username")); + } - if (node.getValue("password") != null) { - rabbitConfig.put("password", node.getValue("password")); - } + if (node.getValue("password") != null) { + rabbitConfig.put("password", node.getValue("password")); + } - if (node.getValue("uri") != null) { - rabbitConfig.put("uri", node.getValue("uri")); - } + if (node.getValue("uri") != null) { + rabbitConfig.put("uri", node.getValue("uri")); + } - if (rabbitConfig.size() == 3) { + if (rabbitConfig.size() == 3) { + rabbitConnectionInfo = new RabbitConnectionInfo(rabbitConfig.get("username"), rabbitConfig.get("password"), rabbitConfig.get("uri")); + try { connectRabbit(); + } catch (IOException e1) { + logger.fatal(e); } } - }); - - this.discoverer.addHandlers(true, Collections.emptyList(), changedValueHandlers, Collections.emptyList()); + } } /** * Connect to rabbitmq using the rabbitconfig, then connect the publisher and subscriber * Adds the handlers for listening to incoming game messages */ - private void connectRabbit() { - if (!isRabbitConnected()) { + private void connectRabbit() throws IOException { + if (!isRabbitConnected() && rabbitConnectionInfo != null) { logger.info("Connecting RabbitMQ..."); - ConnectionFactory connectionFactory = new ConnectionFactory(); - connectionFactory.setUsername(rabbitConfig.get("username")); - connectionFactory.setPassword(rabbitConfig.get("password")); + ConnectionFactory connectionFactory = null; try { - connectionFactory.setUri(rabbitConfig.get("uri")); - } catch (URISyntaxException | NoSuchAlgorithmException | KeyManagementException e) { - logger.fatal(e); + connectionFactory = rabbitConnectionInfo.createConnectionFactory(); + } catch (RabbitConnectionInfo.ConnectionInfoExpiredException e) { + rabbitConnectionInfo = RabbitConnectionInfo.createInstance(discoverer); } // We can connect to localhost, since the visualization does not run within Docker this.subscriber = new RabbitSubscriber(connectionFactory, "visualisation", new JavaSerializer(), discoverer); this.publisher = new RabbitPublisher(connectionFactory, new JavaSerializer(), discoverer); - try { - this.subscriber.connect(); - this.publisher.connect(); - logger.info("Connected RabbitMQ!"); - } catch (IOException e) { - logger.fatal(e); - } + this.subscriber.connect(); + this.publisher.connect(); + logger.info("Connected RabbitMQ!"); this.subscriber.addHandler(CollisionMessage.class, new CollisionMessageHandler()); @@ -335,12 +342,10 @@ private void connectRabbit() { this.subscriber.addHandler(FireBulletMessage.class, new FireBulletMessageHandler()); this.subscriber.addHandler(KillMessage.class, new KillMessageHandler(this.entities)); this.subscriber.addHandler(StateMessage.class, new StateMessageHandler(uiUpdates, this.entities)); + gameFinishedHandler = new GameFinishedHandler(primaryStage); + this.subscriber.addHandler(GameFinishedMessage.class, gameFinishedHandler); - try { - this.subscriber.addTopic(MessageTopic.STATEUPDATES); - } catch (IOException e) { - logger.fatal(e); - } + this.subscriber.addTopic(MessageTopic.STATEUPDATES); } } @@ -354,10 +359,8 @@ private void onRabbitConnect() { /** * Creates the canvas for scrolling and panning. - * - * @param primaryStage - Stage as given by the start method */ - private void setupInterface(Stage primaryStage) { + private void setupInterface() { root = new Group(); primaryStage.setTitle("Drone simulator"); @@ -420,6 +423,7 @@ private void setupArchitectureManagementVisuals() { root.getChildren().add(borderPane); configButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.CONFIG, publisher)); + configButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> gameFinishedHandler.clear()); startButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.START, publisher)); stopButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.STOP, publisher)); pauseButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.PAUSE, publisher)); @@ -455,13 +459,4 @@ private void createDrone(String id) { drone.setDirection(new D3PolarCoordinate(-9999, -9999, -9999)); entities.putIfAbsent(id, drone); } - - /** - * Main method of the visualisation - * - * @param args - args - */ - public static void main(String[] args) { - launch(args); - } } diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java new file mode 100644 index 00000000..83bba1c7 --- /dev/null +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java @@ -0,0 +1,48 @@ +package org.inaetics.dronessimulator.visualisation.messagehandlers; + +import javafx.application.Platform; +import javafx.scene.Scene; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.Window; +import org.inaetics.dronessimulator.common.protocol.GameFinishedMessage; +import org.inaetics.dronessimulator.pubsub.api.Message; +import org.inaetics.dronessimulator.pubsub.api.MessageHandler; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class GameFinishedHandler implements MessageHandler { + private static final AtomicBoolean popupIsQueued = new AtomicBoolean(false); + private final Window mainWindow; + + public GameFinishedHandler(Window mainWindow) { + this.mainWindow = mainWindow; + clear(); + } + + public void clear() { + popupIsQueued.set(false); + } + + @Override + public void handleMessage(Message message) { + GameFinishedMessage gameFinishedMessage = (GameFinishedMessage) message; + if (!popupIsQueued.get()) { + // Avoid throwing IllegalStateException by running from a non-JavaFX thread. + Platform.runLater( + () -> { + final Stage dialog = new Stage(); + dialog.initModality(Modality.APPLICATION_MODAL); + dialog.initOwner(mainWindow); + VBox dialogVbox = new VBox(20); + dialogVbox.getChildren().add(new Text("The game is finished and was won by: " + gameFinishedMessage.getWinner())); + Scene dialogScene = new Scene(dialogVbox, 300, 200); + dialog.setScene(dialogScene); + dialog.show(); + }); + popupIsQueued.set(true); + } + } +} From 8244a472b41c5c3fcad5bf54d02d33afb66f7df7 Mon Sep 17 00:00:00 2001 From: Martijn Date: Thu, 12 Oct 2017 12:12:43 +0200 Subject: [PATCH 2/5] Changed the location where the game events are reduced to one so we will receive only a single pop-up. Also added the functionality to change to the Done state after the game is won. Using the config is now functional and no special tricks need to be executed that can be forgotten. --- .../common/gameevent/GameFinishedEvent.java | 13 ++++++- .../rules/AbstractGameFinishedRule.java | 13 +++++-- .../dronessimulator/visualisation/Game.java | 3 +- .../messagehandlers/GameFinishedHandler.java | 37 +++++++------------ 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java index e1530421..4a31c3c8 100644 --- a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/gameevent/GameFinishedEvent.java @@ -1,11 +1,13 @@ package org.inaetics.dronessimulator.gameengine.common.gameevent; import lombok.RequiredArgsConstructor; +import org.inaetics.dronessimulator.common.architecture.SimulationAction; import org.inaetics.dronessimulator.common.protocol.GameFinishedMessage; import org.inaetics.dronessimulator.common.protocol.ProtocolMessage; +import org.inaetics.dronessimulator.common.protocol.RequestArchitectureStateChangeMessage; import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; -import java.util.Collections; +import java.util.LinkedList; import java.util.List; @RequiredArgsConstructor @@ -14,6 +16,13 @@ public class GameFinishedEvent extends GameEngineEvent { @Override public List getProtocolMessage(IdentifierMapper id_mapper) { - return Collections.singletonList(new GameFinishedMessage(winner)); + List messages = new LinkedList<>(); + messages.add(new GameFinishedMessage(winner)); + //Also tell the architecture manager that the game is over + RequestArchitectureStateChangeMessage requestArchitectureStateChangeMessage = new RequestArchitectureStateChangeMessage(); + requestArchitectureStateChangeMessage.setAction(SimulationAction.GAMEOVER); + messages.add(requestArchitectureStateChangeMessage); + + return messages; } } diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java index 13bce02b..e68ff12b 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java @@ -1,5 +1,6 @@ package org.inaetics.dronessimulator.gameengine.ruleprocessors.rules; +import org.apache.log4j.Logger; import org.inaetics.dronessimulator.gameengine.common.gameevent.CurrentStateEvent; import org.inaetics.dronessimulator.gameengine.common.gameevent.GameEngineEvent; import org.inaetics.dronessimulator.gameengine.common.gameevent.GameFinishedEvent; @@ -7,24 +8,28 @@ import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; public abstract class AbstractGameFinishedRule extends Rule { + private static final Logger logger = Logger.getLogger(AbstractGameFinishedRule.class); + private AtomicBoolean gameFinishedEventWasSend = new AtomicBoolean(false); + @Override public void configRule() { - //no config + logger.debug("Set gameFinishedEventWasSend to false so a new game finished event can be send if this game ends"); + gameFinishedEventWasSend.set(false); } @Override public List process(GameEngineEvent msg) { if (msg instanceof CurrentStateEvent) { CurrentStateEvent currentStateEvent = (CurrentStateEvent) msg; - if (gameIsFinished(currentStateEvent.getCurrentState())) { + if (gameIsFinished(currentStateEvent.getCurrentState()) && !gameFinishedEventWasSend.get()) { + gameFinishedEventWasSend.set(true); return Collections.singletonList(new GameFinishedEvent(getWinner())); } } return Collections.singletonList(msg); - - } protected abstract String getWinner(); diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java index 8cae3e36..3d757121 100644 --- a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java @@ -106,7 +106,7 @@ public class Game extends Application { * Close event handler * When the window closes, rabbitmq and the discoverer disconnect */ - private EventHandler onCloseEventHandler = new EventHandler() { + private EventHandler onCloseEventHandler = new EventHandler() { boolean isClosed = false; @Override @@ -423,7 +423,6 @@ private void setupArchitectureManagementVisuals() { root.getChildren().add(borderPane); configButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.CONFIG, publisher)); - configButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> gameFinishedHandler.clear()); startButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.START, publisher)); stopButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.STOP, publisher)); pauseButton.setOnMouseClicked(new ArchitectureButtonEventHandler(SimulationAction.PAUSE, publisher)); diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java index 83bba1c7..3552dd94 100644 --- a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java @@ -7,42 +7,33 @@ import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.Window; +import org.apache.log4j.Logger; import org.inaetics.dronessimulator.common.protocol.GameFinishedMessage; import org.inaetics.dronessimulator.pubsub.api.Message; import org.inaetics.dronessimulator.pubsub.api.MessageHandler; -import java.util.concurrent.atomic.AtomicBoolean; - public class GameFinishedHandler implements MessageHandler { - private static final AtomicBoolean popupIsQueued = new AtomicBoolean(false); + private static final Logger logger = Logger.getLogger(GameFinishedHandler.class); private final Window mainWindow; public GameFinishedHandler(Window mainWindow) { this.mainWindow = mainWindow; - clear(); - } - - public void clear() { - popupIsQueued.set(false); } @Override public void handleMessage(Message message) { GameFinishedMessage gameFinishedMessage = (GameFinishedMessage) message; - if (!popupIsQueued.get()) { - // Avoid throwing IllegalStateException by running from a non-JavaFX thread. - Platform.runLater( - () -> { - final Stage dialog = new Stage(); - dialog.initModality(Modality.APPLICATION_MODAL); - dialog.initOwner(mainWindow); - VBox dialogVbox = new VBox(20); - dialogVbox.getChildren().add(new Text("The game is finished and was won by: " + gameFinishedMessage.getWinner())); - Scene dialogScene = new Scene(dialogVbox, 300, 200); - dialog.setScene(dialogScene); - dialog.show(); - }); - popupIsQueued.set(true); - } + + // Avoid throwing IllegalStateException by running from a non-JavaFX thread. + Platform.runLater(() -> { + final Stage dialog = new Stage(); + dialog.initModality(Modality.APPLICATION_MODAL); + dialog.initOwner(mainWindow); + VBox dialogVbox = new VBox(20); + dialogVbox.getChildren().add(new Text("The game is finished and was won by: " + gameFinishedMessage.getWinner())); + Scene dialogScene = new Scene(dialogVbox, 300, 200); + dialog.setScene(dialogScene); + dialog.show(); + }); } } From f565387b466c5cad694de809b8800d5d36479e32 Mon Sep 17 00:00:00 2001 From: Martijn Date: Thu, 12 Oct 2017 16:21:08 +0200 Subject: [PATCH 3/5] Also added the draw and changed the value of the winner that is send to reflect actual names instead of only game-engine ids --- .../gameengine/common/state/Drone.java | 37 ++++++++++++------- .../gameengine/test/TestGameDamage.java | 4 +- .../gameengine/GameEngine.java | 13 +++++-- .../TestGameSubscriberMessageHandler.java | 2 +- .../gameengine/test/TestGameStateManager.java | 4 +- .../ruleprocessors/RuleProcessors.java | 14 ++----- .../gameengine/ruleprocessors/RuleSets.java | 2 +- .../rules/AbstractGameFinishedRule.java | 24 ++++++++++-- .../deathmatch/DeathmatchGameFinished.java | 14 ++++++- .../rules/teamplay/TeamplayGameFinished.java | 9 +++-- .../rabbitmq/subscriber/RabbitSubscriber.java | 19 ++++++---- .../messagehandlers/GameFinishedHandler.java | 8 +++- 12 files changed, 101 insertions(+), 49 deletions(-) diff --git a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/state/Drone.java b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/state/Drone.java index 1961b744..12fc62a5 100644 --- a/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/state/Drone.java +++ b/implementation/gameengine/common/src/main/java/org/inaetics/dronessimulator/gameengine/common/state/Drone.java @@ -1,6 +1,7 @@ package org.inaetics.dronessimulator.gameengine.common.state; import lombok.EqualsAndHashCode; +import lombok.Getter; import org.inaetics.dronessimulator.common.protocol.EntityType; import org.inaetics.dronessimulator.common.vector.D3PolarCoordinate; import org.inaetics.dronessimulator.common.vector.D3Vector; @@ -10,36 +11,46 @@ */ @EqualsAndHashCode(callSuper = true) public class Drone extends HealthGameEntity { - /** The maximum health of a drone. */ + /** + * The maximum health of a drone. + */ public static final int DRONE_MAX_HEALTH = 100; + @Getter + private final String team; /** * Construction of a drone. - * @param id Id of the new drone. - * @param position Position of the new drone. - * @param velocity Velocity of the new drone. + * + * @param id Id of the new drone. + * @param position Position of the new drone. + * @param velocity Velocity of the new drone. * @param acceleration Acceleration of the new drone. - * @param direction Direction of the new drone. + * @param direction Direction of the new drone. */ - public Drone(int id, D3Vector position, D3Vector velocity, D3Vector acceleration, D3PolarCoordinate direction) { + public Drone(int id, String team, D3Vector position, D3Vector velocity, D3Vector acceleration, D3PolarCoordinate direction) { super(id, DRONE_MAX_HEALTH, position, velocity, acceleration, direction); + this.team = team; } /** * Construction of a drone. - * @param id Id of the new drone. - * @param currentHP Max hp of the new drone. - * @param position Position of the new drone. - * @param velocity Velocity of the new drone. + * + * @param id Id of the new drone. + * @param currentHP Max hp of the new drone. + * @param position Position of the new drone. + * @param velocity Velocity of the new drone. * @param acceleration Acceleration of the new drone. - * @param direction Direction of the new drone. + * @param direction Direction of the new drone. */ - public Drone(int id, int currentHP, D3Vector position, D3Vector velocity, D3Vector acceleration, D3PolarCoordinate direction) { + public Drone(int id, String team, int currentHP, D3Vector position, D3Vector velocity, D3Vector acceleration, D3PolarCoordinate direction) { super(id, currentHP, position, velocity, acceleration, direction); + this.team = team; + } /** * Return the protocol entity type of the game entity. + * * @return Which type the game entity is in terms of the protocol. */ @Override @@ -49,6 +60,6 @@ public EntityType getType() { @Override public synchronized Drone deepCopy() { - return new Drone(this.getEntityId(), this.getHp(), this.getPosition(), this.getVelocity(), this.getAcceleration(), this.getDirection()); + return new Drone(this.getEntityId(), this.getTeam(), this.getHp(), this.getPosition(), this.getVelocity(), this.getAcceleration(), this.getDirection()); } } \ No newline at end of file diff --git a/implementation/gameengine/common/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameDamage.java b/implementation/gameengine/common/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameDamage.java index f301a0fc..e70114a2 100644 --- a/implementation/gameengine/common/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameDamage.java +++ b/implementation/gameengine/common/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameDamage.java @@ -12,9 +12,9 @@ public class TestGameDamage { @Test public void testDamage() { - Drone shooter = new Drone(1, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); + Drone shooter = new Drone(1, "team1", new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); Bullet bullet = new Bullet(2, 100, shooter, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); - Drone target = new Drone(3, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); + Drone target = new Drone(3, "team2", new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); target.damage(bullet.getDmg()); diff --git a/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java b/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java index 4a7d32cb..4d66a549 100644 --- a/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java +++ b/implementation/gameengine/gameengine/src/main/java/org/inaetics/dronessimulator/gameengine/GameEngine.java @@ -13,9 +13,7 @@ import org.inaetics.dronessimulator.discovery.api.DiscoveryPath; import org.inaetics.dronessimulator.discovery.api.DuplicateName; import org.inaetics.dronessimulator.discovery.api.Instance; -import org.inaetics.dronessimulator.discovery.api.discoverynode.DiscoveryNode; -import org.inaetics.dronessimulator.discovery.api.discoverynode.NodeEventHandler; -import org.inaetics.dronessimulator.discovery.api.discoverynode.Type; +import org.inaetics.dronessimulator.discovery.api.discoverynode.*; import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.AddedNode; import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.RemovedNode; import org.inaetics.dronessimulator.discovery.api.instances.GameEngineInstance; @@ -31,6 +29,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; /** * Wrapper around PhysicsEngine. Sets up and connects all handlers with each other. @@ -174,7 +173,13 @@ public void start() throws DuplicateName, IOException { , 50); numberSpawned++; - this.m_physicsEngineDriver.addNewEntity(new Drone(gameengineId, Drone.DRONE_MAX_HEALTH, position, new D3Vector(), new D3Vector(), new D3PolarCoordinate()), protocolId); + String droneteam = "unknown_team"; + Optional droneId = m_id_mapper.fromGameEngineToProtocolId(gameengineId); + if (droneId.isPresent()) { + DiscoveryStoredNode droneInfo = m_discoverer.getNode(new Instance(Type.DRONE, Group.DRONE, droneId.get())); + droneteam = droneInfo.getValues().get("team"); + } + this.m_physicsEngineDriver.addNewEntity(new Drone(gameengineId, droneteam, Drone.DRONE_MAX_HEALTH, position, new D3Vector(), new D3Vector(), new D3PolarCoordinate()), protocolId); logger.info("Added new drone " + protocolId + " as " + gameengineId); } }); diff --git a/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java b/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java index b003c207..af4537ec 100644 --- a/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java +++ b/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java @@ -40,7 +40,7 @@ public void init() { int gameengineId = this.id_mapper.getNewGameEngineId(); String protocolId = "1"; - this.drone = new Drone(gameengineId, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); + this.drone = new Drone(gameengineId, null, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); this.id_mapper.setMapping(gameengineId, protocolId); this.stateManager.addEntityState(drone); diff --git a/implementation/gameengine/gamestate-manager/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameStateManager.java b/implementation/gameengine/gamestate-manager/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameStateManager.java index 1eb19fea..78194fdf 100644 --- a/implementation/gameengine/gamestate-manager/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameStateManager.java +++ b/implementation/gameengine/gamestate-manager/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameStateManager.java @@ -21,7 +21,7 @@ public void init() { @Test public void testAdd() { - Drone drone = new Drone(1, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); + Drone drone = new Drone(1, null, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); this.gameStateManager.addEntityState(drone); this.gameStateManager.addEntityState(new Bullet(2, 100, drone, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate())); @@ -33,7 +33,7 @@ public void testAdd() { @Test public void testRemove() { - Drone drone = new Drone(1, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); + Drone drone = new Drone(1, null, new D3Vector(), new D3Vector(), new D3Vector(), new D3PolarCoordinate()); this.gameStateManager.addEntityState(drone); Assert.assertEquals(drone, this.gameStateManager.getById(1)); diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java index e00a42b2..762816b4 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleProcessors.java @@ -27,17 +27,9 @@ public class RuleProcessors extends Thread implements IRuleProcessors { /** * The physics engine driver to get events from. */ - private IPhysicsEngineDriver m_driver; - - /** - * The publisher to send messages to. - */ - private Publisher m_publisher; - - /** - * The identifier mapper. - */ - private IdentifierMapper m_id_mapper; + private volatile IPhysicsEngineDriver m_driver; + private volatile Publisher m_publisher; + private volatile IdentifierMapper m_id_mapper; /** * Queue of the events to process. diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java index 1def0bb3..7825a7d3 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java @@ -20,7 +20,7 @@ public static Rule[] getRulesForGameMode(GameMode gameMode, Publisher publisher, , new KillEntitiesRule() , new RemoveStrayBullets() , new RemoveStaleStateData() - , new DeathmatchGameFinished() + , new DeathmatchGameFinished(idMapper) , new SendMessages(publisher, idMapper) }; break; diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java index e68ff12b..8bf4ab1f 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/AbstractGameFinishedRule.java @@ -1,10 +1,13 @@ package org.inaetics.dronessimulator.gameengine.ruleprocessors.rules; import org.apache.log4j.Logger; +import org.inaetics.dronessimulator.common.protocol.EntityType; import org.inaetics.dronessimulator.gameengine.common.gameevent.CurrentStateEvent; import org.inaetics.dronessimulator.gameengine.common.gameevent.GameEngineEvent; import org.inaetics.dronessimulator.gameengine.common.gameevent.GameFinishedEvent; +import org.inaetics.dronessimulator.gameengine.common.state.Drone; import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; +import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; import java.util.Collections; import java.util.List; @@ -12,8 +15,13 @@ public abstract class AbstractGameFinishedRule extends Rule { private static final Logger logger = Logger.getLogger(AbstractGameFinishedRule.class); + protected final IdentifierMapper idMapper; private AtomicBoolean gameFinishedEventWasSend = new AtomicBoolean(false); + public AbstractGameFinishedRule(IdentifierMapper idMapper) { + this.idMapper = idMapper; + } + @Override public void configRule() { logger.debug("Set gameFinishedEventWasSend to false so a new game finished event can be send if this game ends"); @@ -24,14 +32,24 @@ public void configRule() { public List process(GameEngineEvent msg) { if (msg instanceof CurrentStateEvent) { CurrentStateEvent currentStateEvent = (CurrentStateEvent) msg; - if (gameIsFinished(currentStateEvent.getCurrentState()) && !gameFinishedEventWasSend.get()) { - gameFinishedEventWasSend.set(true); - return Collections.singletonList(new GameFinishedEvent(getWinner())); + if (!gameFinishedEventWasSend.get()) { + if (gameIsFinished(currentStateEvent.getCurrentState())) { + gameFinishedEventWasSend.set(true); + return Collections.singletonList(new GameFinishedEvent(getWinner())); + } else if (noDronesLeft(currentStateEvent.getCurrentState())) { + //This is a very unlikely case because there will probably be an order in which the drones are killed. + gameFinishedEventWasSend.set(true); + return Collections.singletonList(new GameFinishedEvent(null)); + } } } return Collections.singletonList(msg); } + private boolean noDronesLeft(List currentState) { + return currentState.stream().filter(gameEntity -> EntityType.DRONE.equals(gameEntity.getType())).map(gameEntity -> ((Drone) gameEntity)).filter(drone -> drone.getHp() > 0).count() == 0; + } + protected abstract String getWinner(); protected abstract boolean gameIsFinished(List currentState); diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java index 79de68fb..4db6003e 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/deathmatch/DeathmatchGameFinished.java @@ -3,16 +3,28 @@ import org.inaetics.dronessimulator.common.protocol.EntityType; import org.inaetics.dronessimulator.gameengine.common.state.Drone; import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; +import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.AbstractGameFinishedRule; import java.util.List; +import java.util.Optional; public class DeathmatchGameFinished extends AbstractGameFinishedRule { private int winner; + public DeathmatchGameFinished(IdentifierMapper idMapper) { + super(idMapper); + } + @Override protected String getWinner() { - return String.valueOf(winner); + String droneName = String.valueOf(winner); + Optional droneId = idMapper.fromGameEngineToProtocolId(winner); + if (droneId.isPresent()) { + droneName = droneId.get(); + } + + return droneName; } @Override diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java index 1635e694..febdfca3 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java @@ -3,6 +3,7 @@ import org.inaetics.dronessimulator.common.protocol.EntityType; import org.inaetics.dronessimulator.gameengine.common.state.Drone; import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; +import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.AbstractGameFinishedRule; import java.util.List; @@ -12,13 +13,15 @@ public class TeamplayGameFinished extends AbstractGameFinishedRule { private Map dronesPerTeam; + public TeamplayGameFinished(IdentifierMapper idMapper) { + super(idMapper); + } + @Override protected boolean gameIsFinished(List currentState) { dronesPerTeam = currentState.stream().filter(gameEntity -> EntityType.DRONE.equals(gameEntity.getType())).map(gameEntity -> ((Drone) gameEntity)) .filter(drone -> drone.getHp() > 0).collect(Collectors.groupingBy( - drone -> { - return String.valueOf(drone.getEntityId()); //todo replace with teamname - }, Collectors.counting() + Drone::getTeam, Collectors.counting() )); return dronesPerTeam.size() == 1; } diff --git a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java index 5e3f24bd..d8587303 100644 --- a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java +++ b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java @@ -26,7 +26,7 @@ public class RabbitSubscriber extends RabbitConnection implements Subscriber { private String identifier; /** The handlers for each message class this subscriber processes. */ - private Map, Collection> handlers; + private static Map, Collection> handlers = new HashMap<>(); /** The topics this subscriber is subscribed to. */ private Map topics; @@ -51,6 +51,7 @@ public RabbitSubscriber(ConnectionFactory connectionFactory, String identifier, * @param connectionFactory The RabbitMQ connection factory to use when starting a new connection. * @param identifier The identifier for this subscriber. This is used as queue name. */ + @SuppressWarnings("unused") //Suppress unused since it will be used by OSGi public RabbitSubscriber(ConnectionFactory connectionFactory, String identifier) { super(connectionFactory); this.construct(identifier); @@ -61,6 +62,7 @@ public RabbitSubscriber(ConnectionFactory connectionFactory, String identifier) * injected later on and the connection factory will be built from a discoverable config. * @param identifier The identifier for this subscriber. This is used as queue name. */ + @SuppressWarnings("unused") //Suppress unused since it will be used by OSGi public RabbitSubscriber(String identifier) { super(); this.construct(identifier); @@ -71,6 +73,7 @@ public RabbitSubscriber(String identifier) { * injected later on and the connection factory will be built from a discoverable config. The identifier will be * set to a generated UUID. */ + @SuppressWarnings("unused") //Suppress unused since it will be used by OSGi public RabbitSubscriber() { this(UUID.randomUUID().toString()); } @@ -82,7 +85,6 @@ private void construct(String identifier) { assert identifier != null; this.identifier = identifier; - this.handlers = new HashMap<>(); this.topics = new HashMap<>(); logger.debug("Initialized RabbitMQ subscriber with identifier {}", identifier); @@ -133,7 +135,7 @@ public void removeTopic(Topic topic) throws IOException { @Override public void addHandler(Class messageClass, MessageHandler handler) { // Create new set for this message class if needed - Collection handlers = this.handlers.computeIfAbsent(messageClass, k -> new HashSet<>()); + Collection handlers = RabbitSubscriber.handlers.computeIfAbsent(messageClass, k -> new HashSet<>()); handlers.add(handler); logger.debug("Handler {} set for message class {}", handler, messageClass); } @@ -145,7 +147,7 @@ public void addHandler(Class messageClass, MessageHandler han */ @Override public void removeHandler(Class messageClass, MessageHandler handler) { - Collection handlers = this.handlers.get(messageClass); + Collection handlers = RabbitSubscriber.handlers.get(messageClass); // Remove the handler for the class if any handler set is defined if (handlers != null) { @@ -162,7 +164,7 @@ public void removeHandler(Class messageClass, MessageHandler @Override public void receive(Message message) { logger.debug("Message {} received by queue {}", message.toString(), this.identifier); - Collection handlers = this.handlers.get(message.getClass()); + Collection handlers = RabbitSubscriber.handlers.get(message.getClass()); // Pass the message to every defined handler if (handlers != null) { @@ -170,9 +172,12 @@ public void receive(Message message) { handler.handleMessage(message); } } else { - Collection messageTypes = this.handlers.keySet().stream().map(Class::toString).collect(Collectors.toSet()); + Collection messageTypes = RabbitSubscriber.handlers.keySet().stream().map(Class::toString).collect(Collectors.toSet()); logger.warn("Message {} was received but is unroutable", message.toString()); - logger.debug("Handlers available for messages types {}", String.join(",", messageTypes)); + if (logger.isDebugEnabled() && messageTypes.size() == 0) { + messageTypes.add("no message types found that can be handled. There are " + RabbitSubscriber.handlers.size() + " handlers available in total."); + logger.debug("Handlers available for messages types: " + String.join(",", messageTypes)); + } } } diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java index 3552dd94..113f4e1f 100644 --- a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java @@ -30,7 +30,13 @@ public void handleMessage(Message message) { dialog.initModality(Modality.APPLICATION_MODAL); dialog.initOwner(mainWindow); VBox dialogVbox = new VBox(20); - dialogVbox.getChildren().add(new Text("The game is finished and was won by: " + gameFinishedMessage.getWinner())); + if (gameFinishedMessage.getWinner() == null) { + //There is no winner defined. This means that there was a draw. + dialogVbox.getChildren().add(new Text("The game is finished and ended in a draw")); + + } else { + dialogVbox.getChildren().add(new Text("The game is finished and was won by: " + gameFinishedMessage.getWinner())); + } Scene dialogScene = new Scene(dialogVbox, 300, 200); dialog.setScene(dialogScene); dialog.show(); From 54441a90944d3766e0b56f17d6ed983f26d0a8c7 Mon Sep 17 00:00:00 2001 From: Martijn Date: Thu, 12 Oct 2017 16:49:28 +0200 Subject: [PATCH 4/5] Changed the popup to use the build-in popups --- .../pubsub/api/subscriber/Subscriber.java | 2 ++ .../rabbitmq/subscriber/RabbitSubscriber.java | 10 +++++++ .../dronessimulator/visualisation/Game.java | 4 +-- .../messagehandlers/GameFinishedHandler.java | 28 +++++++++---------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/implementation/pubsub/api/src/main/java/org/inaetics/dronessimulator/pubsub/api/subscriber/Subscriber.java b/implementation/pubsub/api/src/main/java/org/inaetics/dronessimulator/pubsub/api/subscriber/Subscriber.java index 414f698a..6f99e952 100644 --- a/implementation/pubsub/api/src/main/java/org/inaetics/dronessimulator/pubsub/api/subscriber/Subscriber.java +++ b/implementation/pubsub/api/src/main/java/org/inaetics/dronessimulator/pubsub/api/subscriber/Subscriber.java @@ -30,6 +30,8 @@ public interface Subscriber { */ void addHandler(Class messageClass, MessageHandler handler); + void addHandlerIfNotExists(Class messageClass, MessageHandler handler); + /** * Removes a message handler from this subscriber. * @param messageClass The message class to remove the handler for. diff --git a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java index d8587303..732a9f4a 100644 --- a/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java +++ b/implementation/pubsub/rabbitmq/subscriber/src/main/java/org/inaetics/dronessimulator/pubsub/rabbitmq/subscriber/RabbitSubscriber.java @@ -140,6 +140,16 @@ public void addHandler(Class messageClass, MessageHandler han logger.debug("Handler {} set for message class {}", handler, messageClass); } + @Override + public void addHandlerIfNotExists(Class messageClass, MessageHandler handler) { + // Create new set for this message class if needed + Collection handlers = RabbitSubscriber.handlers.computeIfAbsent(messageClass, k -> new HashSet<>()); + if (handlers.stream().filter(h -> h.getClass().equals(handler.getClass())).count() == 0) { + handlers.add(handler); + logger.debug("Handler {} set for message class {}", handler, messageClass); + } + } + /** * Removes the given handler for the given message class. * @param messageClass The message class to remove the handler for. diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java index 3d757121..7bf1ec4f 100644 --- a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/Game.java @@ -129,7 +129,6 @@ public void handle(WindowEvent t) { } }; private RabbitConnectionInfo rabbitConnectionInfo; - private GameFinishedHandler gameFinishedHandler; /** * Instantiates a new game object @@ -342,8 +341,7 @@ private void connectRabbit() throws IOException { this.subscriber.addHandler(FireBulletMessage.class, new FireBulletMessageHandler()); this.subscriber.addHandler(KillMessage.class, new KillMessageHandler(this.entities)); this.subscriber.addHandler(StateMessage.class, new StateMessageHandler(uiUpdates, this.entities)); - gameFinishedHandler = new GameFinishedHandler(primaryStage); - this.subscriber.addHandler(GameFinishedMessage.class, gameFinishedHandler); + this.subscriber.addHandlerIfNotExists(GameFinishedMessage.class, new GameFinishedHandler(primaryStage)); this.subscriber.addTopic(MessageTopic.STATEUPDATES); } diff --git a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java index 113f4e1f..df7ea742 100644 --- a/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java +++ b/implementation/visualisation/src/main/java/org/inaetics/dronessimulator/visualisation/messagehandlers/GameFinishedHandler.java @@ -1,11 +1,9 @@ package org.inaetics.dronessimulator.visualisation.messagehandlers; import javafx.application.Platform; -import javafx.scene.Scene; -import javafx.scene.layout.VBox; -import javafx.scene.text.Text; -import javafx.stage.Modality; -import javafx.stage.Stage; +import javafx.scene.control.Alert; +import javafx.scene.layout.Region; +import javafx.stage.StageStyle; import javafx.stage.Window; import org.apache.log4j.Logger; import org.inaetics.dronessimulator.common.protocol.GameFinishedMessage; @@ -26,20 +24,22 @@ public void handleMessage(Message message) { // Avoid throwing IllegalStateException by running from a non-JavaFX thread. Platform.runLater(() -> { - final Stage dialog = new Stage(); - dialog.initModality(Modality.APPLICATION_MODAL); - dialog.initOwner(mainWindow); - VBox dialogVbox = new VBox(20); + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("The game finished"); if (gameFinishedMessage.getWinner() == null) { //There is no winner defined. This means that there was a draw. - dialogVbox.getChildren().add(new Text("The game is finished and ended in a draw")); + alert.setContentText("The game is finished and ended in a draw"); } else { - dialogVbox.getChildren().add(new Text("The game is finished and was won by: " + gameFinishedMessage.getWinner())); + alert.setContentText("The game is finished and was won by: " + gameFinishedMessage.getWinner()); } - Scene dialogScene = new Scene(dialogVbox, 300, 200); - dialog.setScene(dialogScene); - dialog.show(); + alert.initStyle(StageStyle.UTILITY); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.getDialogPane().setMinWidth(Region.USE_PREF_SIZE); + alert.setHeaderText(null); + alert.setResizable(true); + + alert.show(); }); } } From 836fd6fe7d8393a68e9531fdc65ef782c406fc2d Mon Sep 17 00:00:00 2001 From: Martijn Date: Fri, 27 Oct 2017 09:52:53 +0200 Subject: [PATCH 5/5] Fixed merge conflicts and added the teamplay game finished rule. --- .../TestGameSubscriberMessageHandler.java | 42 ++++++++++++++++++- .../gameengine/ruleprocessors/RuleSets.java | 2 + .../rules/teamplay/TeamplayGameFinished.java | 6 ++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java b/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java index af4537ec..1771df72 100644 --- a/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java +++ b/implementation/gameengine/gameengine/src/test/java/org/inaetics/dronessimulator/gameengine/test/TestGameSubscriberMessageHandler.java @@ -3,6 +3,14 @@ import org.inaetics.dronessimulator.common.protocol.*; import org.inaetics.dronessimulator.common.vector.D3PolarCoordinate; import org.inaetics.dronessimulator.common.vector.D3Vector; +import org.inaetics.dronessimulator.discovery.api.Discoverer; +import org.inaetics.dronessimulator.discovery.api.DuplicateName; +import org.inaetics.dronessimulator.discovery.api.Instance; +import org.inaetics.dronessimulator.discovery.api.discoverynode.DiscoveryStoredNode; +import org.inaetics.dronessimulator.discovery.api.discoverynode.NodeEventHandler; +import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.AddedNode; +import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.ChangedValue; +import org.inaetics.dronessimulator.discovery.api.discoverynode.discoveryevent.RemovedNode; import org.inaetics.dronessimulator.gameengine.common.state.Bullet; import org.inaetics.dronessimulator.gameengine.common.state.Drone; import org.inaetics.dronessimulator.gameengine.gamestatemanager.GameStateManager; @@ -15,11 +23,16 @@ import org.junit.Before; import org.junit.Test; +import java.io.IOException; +import java.util.List; +import java.util.Map; + public class TestGameSubscriberMessageHandler { private MockPhysicsEngineDriver mockDriver; private IdentifierMapperService id_mapper; private GameStateManager stateManager; + private MockDiscoverer mockDiscoverer; private DamageMessageHandler damageMessageHandler; private FireBulletMessageHandler fireBulletMessageHandler; @@ -35,7 +48,7 @@ public void init() { this.mockDriver = new MockPhysicsEngineDriver(this.id_mapper); this.damageMessageHandler = new DamageMessageHandler(this.mockDriver, this.id_mapper, this.stateManager); this.fireBulletMessageHandler = new FireBulletMessageHandler(this.mockDriver, this.id_mapper, this.stateManager); - this.killMessageHandler = new KillMessageHandler(this.mockDriver, this.id_mapper, this.stateManager); + this.killMessageHandler = new KillMessageHandler(this.mockDriver, this.id_mapper, this.stateManager, this.mockDiscoverer); this.movementMessageHandler = new MovementMessageHandler(this.mockDriver, this.id_mapper, this.stateManager); int gameengineId = this.id_mapper.getNewGameEngineId(); @@ -120,4 +133,31 @@ public void testFireBullet() { Assert.assertEquals(new Bullet(2, 50, drone, new D3Vector(3,2,1), new D3Vector(2,3,1), new D3Vector(1,2,3), new D3PolarCoordinate()), mockDriver.getAdded()); } + + private class MockDiscoverer implements Discoverer { + @Override + public void register(Instance instance) throws DuplicateName, IOException { + + } + + @Override + public void unregister(Instance instance) throws IOException { + + } + + @Override + public Instance updateProperties(Instance instance, Map properties) throws IOException { + return null; + } + + @Override + public void addHandlers(boolean replay, List> addHandlers, List> changedValueHandlers, List> removedHandlers) { + + } + + @Override + public DiscoveryStoredNode getNode(Instance instance) { + return null; + } + } } diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java index 258459c6..8d53b942 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/RuleSets.java @@ -7,6 +7,7 @@ import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch.CollisionRule; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch.DeathmatchGameFinished; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.deathmatch.KillEntitiesRule; +import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.teamplay.TeamplayGameFinished; import org.inaetics.dronessimulator.pubsub.api.publisher.Publisher; import java.util.LinkedList; @@ -25,6 +26,7 @@ public static List getRulesForGameMode(GameMode gameMode, Publisher publis case TEAMPLAY: result.add(new KillEntitiesRule()); result.add(new CollisionRule()); + result.add(new TeamplayGameFinished(idMapper)); break; } result.add(new RemoveStrayBullets()); diff --git a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java index febdfca3..bde4a3bd 100644 --- a/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java +++ b/implementation/gameengine/ruleprocessors/src/main/java/org/inaetics/dronessimulator/gameengine/ruleprocessors/rules/teamplay/TeamplayGameFinished.java @@ -1,15 +1,18 @@ package org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.teamplay; +import lombok.extern.log4j.Log4j; import org.inaetics.dronessimulator.common.protocol.EntityType; import org.inaetics.dronessimulator.gameengine.common.state.Drone; import org.inaetics.dronessimulator.gameengine.common.state.GameEntity; import org.inaetics.dronessimulator.gameengine.identifiermapper.IdentifierMapper; import org.inaetics.dronessimulator.gameengine.ruleprocessors.rules.AbstractGameFinishedRule; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +@Log4j public class TeamplayGameFinished extends AbstractGameFinishedRule { private Map dronesPerTeam; @@ -21,8 +24,9 @@ public TeamplayGameFinished(IdentifierMapper idMapper) { protected boolean gameIsFinished(List currentState) { dronesPerTeam = currentState.stream().filter(gameEntity -> EntityType.DRONE.equals(gameEntity.getType())).map(gameEntity -> ((Drone) gameEntity)) .filter(drone -> drone.getHp() > 0).collect(Collectors.groupingBy( - Drone::getTeam, Collectors.counting() + Drone::getTeamname, Collectors.counting() )); + log.info("Checking winconditions for teamplay. This is the current map: " + Arrays.toString(dronesPerTeam.entrySet().toArray())); return dronesPerTeam.size() == 1; }