From 610f0b092fb3a0faaa88058321a29f1f0fbaddb1 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Fri, 14 Feb 2020 21:11:40 -0500 Subject: [PATCH] Test Fixes (#344) * building guid fixes for zone tests; spawn pad control allocates messaging targets more carefully; additional check for building registration in ZoneActor * the nature of the amenity/zone interaction changed --- .../pad/VehicleSpawnControl.scala | 11 +++- .../serverobject/structures/Building.scala | 24 ++++----- .../net/psforever/objects/zones/Zone.scala | 17 +++---- .../psforever/objects/zones/ZoneActor.scala | 11 ++-- .../src/test/scala/objects/UtilityTest.scala | 12 ++--- common/src/test/scala/objects/ZoneTest.scala | 50 +++++++++---------- .../src/main/scala/WorldSessionActor.scala | 2 +- .../actor/objects/VehicleSpawnPadTest.scala | 21 ++++---- 8 files changed, 77 insertions(+), 71 deletions(-) diff --git a/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala index 200da469..574c9d31 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala @@ -201,11 +201,18 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase * @param recipients all of the other customers who will be receiving the message */ def BlockedReminder(blockedOrder : VehicleSpawnControl.Order, recipients : Seq[VehicleSpawnControl.Order]) : Unit = { - val relevantRecipients = blockedOrder.vehicle.Seats(0).Occupant.orElse(pad.Zone.GUID(blockedOrder.vehicle.Owner)) match { + val user = blockedOrder.vehicle.Seats(0).Occupant + .orElse(pad.Zone.GUID(blockedOrder.vehicle.Owner)) + .orElse(pad.Zone.GUID(blockedOrder.DriverGUID)) + val relevantRecipients = user match { + case Some(p : Player) if !p.HasGUID => + recipients.iterator + case Some(p : Player) if blockedOrder.driver == p => + (blockedOrder +: recipients).iterator case Some(p : Player) => (VehicleSpawnControl.Order(p, blockedOrder.vehicle) +: recipients).iterator //who took possession of the vehicle case _ => - (blockedOrder +: recipients).iterator //who ordered the vehicle + recipients.iterator } recursiveBlockedReminder(relevantRecipients, if(blockedOrder.vehicle.Health == 0) diff --git a/common/src/main/scala/net/psforever/objects/serverobject/structures/Building.scala b/common/src/main/scala/net/psforever/objects/serverobject/structures/Building.scala index 04fd79d9..0bf1328e 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/structures/Building.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/structures/Building.scala @@ -13,12 +13,13 @@ import net.psforever.objects.serverobject.terminals.CaptureTerminal import net.psforever.objects.serverobject.tube.SpawnTube import net.psforever.objects.zones.Zone import net.psforever.packet.game._ -import net.psforever.types.{PlanetSideEmpire, Vector3} +import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} import scalax.collection.{Graph, GraphEdge} import services.Service import services.local.{LocalAction, LocalServiceMessage} class Building(private val name: String, + private val building_guid : Int, private val map_id : Int, private val zone : Zone, private val buildingType : StructureType.Value, @@ -32,13 +33,8 @@ class Building(private val name: String, private val capitols = List("Thoth", "Voltan", "Neit", "Anguta", "Eisa", "Verica") private var forceDomeActive : Boolean = false super.Zone_=(zone) - - /** - * An overloaded constructor used for phasing out the need to define the building_guid parameter - */ - def this(name: String, building_guid : Int, map_id : Int, zone : Zone, buildingType : StructureType.Value, buildingDefinition : ObjectDefinition) = { - this(name, map_id, zone, buildingType, buildingDefinition) - } + super.GUID_=(PlanetSideGUID(building_guid)) //set + Invalidate() //unset; guid can be used during setup, but does not stop being registered properly later override def toString = name @@ -274,19 +270,19 @@ class Building(private val name: String, } object Building { - final val NoBuilding : Building = new Building(name = "", map_id = 0, Zone.Nowhere, StructureType.Platform, GlobalDefinitions.building) { + final val NoBuilding : Building = new Building(name = "", 0, map_id = 0, Zone.Nowhere, StructureType.Platform, GlobalDefinitions.building) { override def Faction_=(faction : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL override def Amenities_=(obj : Amenity) : List[Amenity] = Nil GUID = net.psforever.types.PlanetSideGUID(0) } def apply(name : String, guid : Int, map_id : Int, zone : Zone, buildingType : StructureType.Value) : Building = { - new Building(name, map_id, zone, buildingType, GlobalDefinitions.building) + new Building(name, guid, map_id, zone, buildingType, GlobalDefinitions.building) } def Structure(buildingType : StructureType.Value, location : Vector3, definition: ObjectDefinition)(name : String, guid : Int, map_id : Int, zone : Zone, context : ActorContext) : Building = { import akka.actor.Props - val obj = new Building(name, map_id, zone, buildingType, definition) + val obj = new Building(name, guid, map_id, zone, buildingType, definition) obj.Position = location obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$map_id-$buildingType-building") obj @@ -295,7 +291,7 @@ object Building { def Structure(buildingType : StructureType.Value, location : Vector3)(name : String, guid : Int, map_id : Int, zone : Zone, context : ActorContext) : Building = { import akka.actor.Props - val obj = new Building(name, map_id, zone, buildingType, GlobalDefinitions.building) + val obj = new Building(name, guid, map_id, zone, buildingType, GlobalDefinitions.building) obj.Position = location obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$map_id-$buildingType-building") obj @@ -303,14 +299,14 @@ object Building { def Structure(buildingType : StructureType.Value)(name : String, guid: Int, map_id : Int, zone : Zone, context : ActorContext) : Building = { import akka.actor.Props - val obj = new Building(name, map_id, zone, buildingType, GlobalDefinitions.building) + val obj = new Building(name, guid, map_id, zone, buildingType, GlobalDefinitions.building) obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$map_id-$buildingType-building") obj } def Structure(buildingType : StructureType.Value, buildingDefinition : ObjectDefinition, location : Vector3)(name: String, guid: Int, id : Int, zone : Zone, context : ActorContext) : Building = { import akka.actor.Props - val obj = new Building(name, id, zone, buildingType, buildingDefinition) + val obj = new Building(name, guid, id, zone, buildingType, buildingDefinition) obj.Position = location obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$id-$buildingType-building") obj diff --git a/common/src/main/scala/net/psforever/objects/zones/Zone.scala b/common/src/main/scala/net/psforever/objects/zones/Zone.scala index 2e3fbcc3..774a951b 100644 --- a/common/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/common/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -31,8 +31,6 @@ import scalax.collection.Graph import scalax.collection.GraphPredef._ import scalax.collection.GraphEdge._ -import scala.util.Success - /** * A server object representing the one-landmass planets as well as the individual subterranean caverns.
*
@@ -408,14 +406,15 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { private def MakeBuildings(implicit context : ActorContext) : PairMap[Int, Building] = { val buildingList = Map.LocalBuildings + val registrationKeys = buildingList.map { + case ((_, building_guid, _), _) => + building_guid -> guid.register(building_guid) + } buildings = buildingList.map({ - case((name, building_guid, map_id), constructor) => - guid.register(building_guid) match { - case Success(registeredGuid) => - val building = constructor.Build(name, building_guid, map_id, this) - registeredGuid.Object = building - building_guid -> building - } + case((name, building_guid, map_id), constructor) if registrationKeys(building_guid).isSuccess => + val building = constructor.Build(name, building_guid, map_id, this) + registrationKeys(building_guid).get.Object = building + building_guid -> building }) buildings } diff --git a/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala b/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala index eef9c7d0..af67b453 100644 --- a/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala +++ b/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala @@ -214,12 +214,17 @@ class ZoneActor(zone : Zone) extends Actor { val validateObject : (Int, PlanetSideGameObject=>Boolean, String) => Boolean = ValidateObject(guid, slog, errors) //check bases - map.ObjectToBuilding.values.toSet[Int].foreach(building_id => - if(zone.Building(building_id).isEmpty) { + map.ObjectToBuilding.values.toSet[Int].foreach(building_id => { + val target = zone.Building(building_id) + if(target.isEmpty) { slog.error(s"expected a building for id #$building_id") errors.incrementAndGet() } - ) + else if(!target.get.HasGUID) { + slog.error(s"building #$building_id was not registered") + errors.incrementAndGet() + } + }) //check base to object associations map.ObjectToBuilding.keys.foreach(object_guid => diff --git a/common/src/test/scala/objects/UtilityTest.scala b/common/src/test/scala/objects/UtilityTest.scala index dcdd50dd..27f07894 100644 --- a/common/src/test/scala/objects/UtilityTest.scala +++ b/common/src/test/scala/objects/UtilityTest.scala @@ -143,7 +143,7 @@ class UtilityTerminalATest extends ActorTest { assert(obj().Actor == ActorRef.noSender) system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" - receiveOne(Duration.create(100, "ms")) //consume and discard + receiveOne(Duration.create(500, "ms")) //consume and discard assert(obj().Actor != ActorRef.noSender) } } @@ -157,7 +157,7 @@ class UtilityTerminalBTest extends ActorTest { assert(obj().Actor == ActorRef.noSender) system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" - receiveOne(Duration.create(100, "ms")) //consume and discard + receiveOne(Duration.create(500, "ms")) //consume and discard assert(obj().Actor != ActorRef.noSender) } } @@ -171,7 +171,7 @@ class UtilityTerminalCTest extends ActorTest { assert(obj().Actor == ActorRef.noSender) system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" - receiveOne(Duration.create(100, "ms")) //consume and discard + receiveOne(Duration.create(500, "ms")) //consume and discard assert(obj().Actor != ActorRef.noSender) } } @@ -185,7 +185,7 @@ class UtilityRespawnTubeTest extends ActorTest { assert(obj().Actor == ActorRef.noSender) system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" - receiveOne(Duration.create(100, "ms")) //consume and discard + receiveOne(Duration.create(500, "ms")) //consume and discard assert(obj().Actor != ActorRef.noSender) } } @@ -199,7 +199,7 @@ class UtilityTelepadTerminalTest extends ActorTest { assert(obj().Actor == ActorRef.noSender) system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" - receiveOne(Duration.create(100, "ms")) //consume and discard + receiveOne(Duration.create(500, "ms")) //consume and discard assert(obj().Actor != ActorRef.noSender) } } @@ -216,7 +216,7 @@ class UtilityInternalTelepadTest extends ActorTest { assert(obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID)) system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" - receiveOne(Duration.create(100, "ms")) //consume and discard + receiveOne(Duration.create(500, "ms")) //consume and discard assert(obj().Actor != ActorRef.noSender) assert(obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID)) } diff --git a/common/src/test/scala/objects/ZoneTest.scala b/common/src/test/scala/objects/ZoneTest.scala index cfb7a281..b92bc1dd 100644 --- a/common/src/test/scala/objects/ZoneTest.scala +++ b/common/src/test/scala/objects/ZoneTest.scala @@ -111,7 +111,7 @@ class ZoneTest extends Specification { val obj = new TestObject() guid1.register(obj, "pool2").isSuccess mustEqual true - guid1.WhichPool(obj) mustEqual Some("pool2") + guid1.WhichPool(obj).contains("pool2") mustEqual true zone.GUID(new NumberPoolHub(new LimitedNumberSource(150))) mustEqual false } @@ -172,29 +172,29 @@ class ZoneActorTest extends ActorTest { "set up spawn groups based on buildings" in { val map6 = new ZoneMap("map6") { LocalBuilding("Building", building_guid = 1, map_id = 1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1)))) - LocalObject(1, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) - LocalObject(2, Terminal.Constructor(Vector3.Zero, GlobalDefinitions.dropship_vehicle_terminal)) - LocalObject(3, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) - ObjectToBuilding(1, 1) + LocalObject(2, SpawnTube.Constructor(Vector3(1,0,0), Vector3.Zero)) + LocalObject(3, Terminal.Constructor(Vector3.Zero, GlobalDefinitions.dropship_vehicle_terminal)) + LocalObject(4, SpawnTube.Constructor(Vector3(1,0,0), Vector3.Zero)) ObjectToBuilding(2, 1) ObjectToBuilding(3, 1) + ObjectToBuilding(4, 1) - LocalBuilding("Building", building_guid = 2, map_id = 2, FoundationBuilder(Building.Structure(StructureType.Building))) - LocalObject(7, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) - ObjectToBuilding(7, 2) + LocalBuilding("Building", building_guid = 5, map_id = 2, FoundationBuilder(Building.Structure(StructureType.Building))) + LocalObject(6, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) + ObjectToBuilding(6, 5) - LocalBuilding("Building", building_guid = 3, map_id = 3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1)))) - LocalObject(4, Terminal.Constructor(Vector3.Zero, GlobalDefinitions.dropship_vehicle_terminal)) - LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) - LocalObject(6, Terminal.Constructor(Vector3.Zero, GlobalDefinitions.dropship_vehicle_terminal)) - ObjectToBuilding(4, 3) - ObjectToBuilding(5, 3) - ObjectToBuilding(6, 3) + LocalBuilding("Building", building_guid = 7, map_id = 3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1)))) + LocalObject(8, Terminal.Constructor(Vector3.Zero, GlobalDefinitions.dropship_vehicle_terminal)) + LocalObject(9, SpawnTube.Constructor(Vector3(1,0,0), Vector3.Zero)) + LocalObject(10, Terminal.Constructor(Vector3.Zero, GlobalDefinitions.dropship_vehicle_terminal)) + ObjectToBuilding(8, 7) + ObjectToBuilding(9, 7) + ObjectToBuilding(10, 7) } val zone = new Zone("test", map6, 1) { override def SetupNumberPools() = { } } zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-init") zone.Actor ! Zone.Init() - expectNoMsg(Duration.create(300, "ms")) + expectNoMsg(Duration.create(1, "seconds")) val groups = zone.SpawnGroups() assert(groups.size == 2) @@ -203,15 +203,15 @@ class ZoneActorTest extends ActorTest { val building1 = zone.SpawnGroups(building) assert(tubes.length == 2) assert(tubes.head == building1.head) - assert(tubes.head.GUID == PlanetSideGUID(1)) + assert(tubes.head.GUID == PlanetSideGUID(2)) assert(tubes(1) == building1(1)) - assert(tubes(1).GUID == PlanetSideGUID(3)) + assert(tubes(1).GUID == PlanetSideGUID(4)) } else if(building.MapId == 3) { val building2 = zone.SpawnGroups(building) assert(tubes.length == 1) assert(tubes.head == building2.head) - assert(tubes.head.GUID == PlanetSideGUID(5)) + assert(tubes.head.GUID == PlanetSideGUID(9)) } else { assert(false) @@ -222,17 +222,17 @@ class ZoneActorTest extends ActorTest { "select spawn points based on the position of the player in reference to buildings" in { val map6 = new ZoneMap("map6") { LocalBuilding("Building", building_guid = 1, map_id = 1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1)))) - LocalObject(1, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) - ObjectToBuilding(1, 1) + LocalObject(2, SpawnTube.Constructor(Vector3(1,0,0), Vector3.Zero)) + ObjectToBuilding(2, 1) LocalBuilding("Building", building_guid = 3, map_id = 3, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(4,4,4)))) - LocalObject(5, SpawnTube.Constructor(Vector3.Zero, Vector3.Zero)) - ObjectToBuilding(5, 3) + LocalObject(4, SpawnTube.Constructor(Vector3(1,0,0), Vector3.Zero)) + ObjectToBuilding(4, 3) } val zone = new Zone("test", map6, 1) { override def SetupNumberPools() = { } } zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-spawn") zone.Actor ! Zone.Init() - expectNoMsg(Duration.create(300, "ms")) + expectNoMsg(Duration.create(1, "seconds")) val player = Player(Avatar("Chord", PlanetSideEmpire.NEUTRAL, CharacterGender.Male, 0, CharacterVoice.Voice5)) val bldg1 = zone.Building(1).get @@ -371,7 +371,7 @@ class ZonePopulationTest extends ActorTest { assert(zone.LivePlayers.size == 1) assert(zone.LivePlayers.head == player) zone.Population ! Zone.Population.Leave(avatar) - val reply = receiveOne(Duration.create(100, "ms")) + val reply = receiveOne(Duration.create(500, "ms")) assert(zone.Players.isEmpty) assert(zone.LivePlayers.isEmpty) assert(reply.isInstanceOf[Zone.Population.PlayerHasLeft]) diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index e5c9a623..be5fa83f 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -2074,7 +2074,7 @@ class WorldSessionActor extends Actor case Mountable.CanMount(obj : FacilityTurret, seat_num) => if(!obj.isUpgrading) { - if(obj.Definition == vanu_sentry_turret) { + if(obj.Definition == GlobalDefinitions.vanu_sentry_turret) { obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.Id, LocalAction.SetEmpire(obj.GUID, player.Faction)) } sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health)) diff --git a/pslogin/src/test/scala/actor/objects/VehicleSpawnPadTest.scala b/pslogin/src/test/scala/actor/objects/VehicleSpawnPadTest.scala index 608cae8c..e39a7227 100644 --- a/pslogin/src/test/scala/actor/objects/VehicleSpawnPadTest.scala +++ b/pslogin/src/test/scala/actor/objects/VehicleSpawnPadTest.scala @@ -210,17 +210,15 @@ object VehicleSpawnPadControlTest { val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy) val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool] + val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5)) + guid.AddPool("test-pool", (0 to 3).toList) + guid.register(vehicle, "test-pool") + guid.register(weapon, "test-pool") + guid.register(weapon.AmmoSlot.Box, "test-pool") val zone = new Zone("test-zone", map, 0) { - override def SetupNumberPools() = { - val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5)) - guid.AddPool("test-pool", (0 to 2).toList) - //do not do this under normal conditions - guid.register(vehicle, "test-pool") - guid.register(weapon, "test-pool") - guid.register(weapon.AmmoSlot.Box, "test-pool") - GUID(guid) - } + override def SetupNumberPools() : Unit = { } } + zone.GUID(guid) zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), s"test-zone-${System.nanoTime()}") zone.Actor ! Zone.Init() @@ -235,9 +233,10 @@ object VehicleSpawnPadControlTest { pad.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], pad), s"test-pad-${System.nanoTime()}") pad.Owner = new Building("Building", building_guid = 0, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building) pad.Owner.Faction = faction + pad.Zone = zone val player = Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute)) - player.GUID = PlanetSideGUID(10) - player.Continent = zone.Id + guid.register(player, "test-pool") + player.Zone = zone player.Spawn //note: pad and vehicle are both at Vector3(1,0,0) so they count as blocking pad.Position = Vector3(1,0,0)