each zone now has access to its own bundle of task resolver objects; primary changes to reflect this has been the simplification of item moving parameters; tests corrected

This commit is contained in:
Jason_DiDonato@yahoo.com 2020-10-10 09:16:56 -04:00
parent 4fc1788e95
commit 69b3a8a4bf
26 changed files with 277 additions and 367 deletions

View file

@ -174,7 +174,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
var accountPersistence: ActorRef = ActorRef.noSender
var galaxyService: ActorRef = ActorRef.noSender
var squadService: ActorRef = ActorRef.noSender
var taskResolver: ActorRef = Actor.noSender
var propertyOverrideManager: ActorRef = Actor.noSender
var cluster: typed.ActorRef[InterstellarClusterService.Command] = Actor.noSender
var _session: Session = Session()
@ -295,7 +294,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
val serviceManager = ServiceManager.serviceManager
serviceManager ! Lookup("accountIntermediary")
serviceManager ! Lookup("accountPersistence")
serviceManager ! Lookup("taskResolver")
serviceManager ! Lookup("galaxy")
serviceManager ! Lookup("squad")
serviceManager ! Lookup("propertyOverrideManager")
@ -376,9 +374,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case LookupResult("accountPersistence", endpoint) =>
accountPersistence = endpoint
log.info("ID: " + session.id + " Got account persistence service " + endpoint)
case LookupResult("taskResolver", endpoint) =>
taskResolver = endpoint
log.info("ID: " + session.id + " Got task resolver service " + endpoint)
case LookupResult("galaxy", endpoint) =>
galaxyService = endpoint
log.info("ID: " + session.id + " Got galaxy service " + endpoint)
@ -1060,17 +1055,17 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//TODO sufficiently delete the tool
sendResponse(ObjectDeleteMessage(tool.GUID, 0))
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.ObjectDelete(player.GUID, tool.GUID))
taskResolver ! GUIDTask.UnregisterEquipment(tool)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterEquipment(tool)(continent.GUID)
val trigger = new BoomerTrigger
trigger.Companion = obj.GUID
obj.Trigger = trigger
val holster = player.Slot(index)
if (holster.Equipment.contains(tool)) {
holster.Equipment = None
taskResolver ! HoldNewEquipmentUp(player, taskResolver)(trigger, index)
continent.tasks ! HoldNewEquipmentUp(player)(trigger, index)
} else {
//don't know where boomer trigger should go; drop it on the ground
taskResolver ! NewItemDrop(player, continent)(trigger)
continent.tasks ! NewItemDrop(player, continent)(trigger)
}
case SessionActor.FinalizeDeployable(obj: ExplosiveDeployable, tool, index) =>
@ -1104,7 +1099,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
log.info(s"FinalizeDeployable: setup for telepad #${guid.guid} in zone ${continent.id}")
obj.Router = routerGUID //necessary; forwards link to the router
DeployableBuildActivity(obj)
RemoveOldEquipmentFromInventory(player, taskResolver)(tool)
RemoveOldEquipmentFromInventory(player)(tool)
//it takes 60s for the telepad to become properly active
continent.LocalEvents ! LocalServiceMessage.Telepads(RouterTelepadActivation.AddTask(obj, continent))
}
@ -1133,11 +1128,11 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//!!only dispatch Zone.Deployable.Dismiss from WorldSessionActor as cleanup if the target deployable was never fully introduced
case Zone.Deployable.DeployableIsDismissed(obj: TurretDeployable) =>
taskResolver ! GUIDTask.UnregisterDeployableTurret(obj)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterDeployableTurret(obj)(continent.GUID)
//!!only dispatch Zone.Deployable.Dismiss from WorldSessionActor as cleanup if the target deployable was never fully introduced
case Zone.Deployable.DeployableIsDismissed(obj) =>
taskResolver ! GUIDTask.UnregisterObjectTask(obj)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterObjectTask(obj)(continent.GUID)
case InterstellarClusterService.ZonesResponse(zones) =>
zones.foreach { zone =>
@ -1240,9 +1235,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
player.avatar = avatar
interstellarFerry match {
case Some(vehicle) if vehicle.PassengerInSeat(player).contains(0) =>
taskResolver ! RegisterDrivenVehicle(vehicle, player)
continent.tasks ! RegisterDrivenVehicle(vehicle, player)
case _ =>
taskResolver ! RegisterNewAvatar(player)
continent.tasks ! RegisterNewAvatar(player)
}
case NewPlayerLoaded(tplayer) =>
@ -1608,14 +1603,14 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
Zoning.Time.Sanctuary
} else {
val playerPosition = player.Position.xy
(continent.Buildings.values
continent.Buildings.values
.filter { building =>
val radius = building.Definition.SOIRadius
Vector3.DistanceSquared(building.Position.xy, playerPosition) < radius * radius
}) match {
} match {
case Nil =>
Zoning.Time.None
case List(building) =>
case List(building: FactionAffinity) =>
if (building.Faction == player.Faction) Zoning.Time.Friendly
else if (building.Faction == PlanetSideEmpire.NEUTRAL) Zoning.Time.Neutral
else Zoning.Time.Enemy
@ -1652,7 +1647,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case Nil =>
//no soi interference
targetBuildings = Nil
case List(building) =>
case List(building: Building) =>
//blocked by a single soi; find space just outside of this soi and confirm no new overlap
val radius = Vector3(0, building.Definition.SOIRadius.toFloat + 5f, 0)
whereToDroppod =
@ -2068,10 +2063,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case (_, guid) => sendResponse(ObjectDeleteMessage(guid, 0))
}
//functionally delete
delete.foreach { case (obj, _) => taskResolver ! GUIDTask.UnregisterEquipment(obj)(continent.GUID) }
delete.foreach { case (obj, _) => continent.tasks ! GUIDTask.UnregisterEquipment(obj)(continent.GUID) }
//redraw
if (maxhand) {
taskResolver ! HoldNewEquipmentUp(player, taskResolver)(
continent.tasks ! HoldNewEquipmentUp(player)(
Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)),
0
)
@ -2146,11 +2141,11 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
(old_holsters ++ old_inventory).foreach {
case (obj, guid) =>
sendResponse(ObjectDeleteMessage(guid, 0))
taskResolver ! GUIDTask.UnregisterEquipment(obj)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterEquipment(obj)(continent.GUID)
}
//redraw
if (maxhand) {
taskResolver ! HoldNewEquipmentUp(player, taskResolver)(
continent.tasks ! HoldNewEquipmentUp(player)(
Tool(GlobalDefinitions.MAXArms(subtype, player.Faction)),
0
)
@ -2189,7 +2184,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
if (Avatar.purchaseCooldowns.contains(item.obj.Definition)) {
avatarActor ! AvatarActor.UpdatePurchaseTime(item.obj.Definition)
}
taskResolver ! PutLoadoutEquipmentInInventory(target, taskResolver)(item.obj, item.start)
continent.tasks ! PutLoadoutEquipmentInInventory(target)(item.obj, item.start)
}
}
}
@ -2538,16 +2533,15 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, false))
case None =>
avatarActor ! AvatarActor.UpdatePurchaseTime(item.Definition)
taskResolver ! BuyNewEquipmentPutInInventory(
continent.tasks ! BuyNewEquipmentPutInInventory(
continent.GUID(tplayer.VehicleSeated) match { case Some(v: Vehicle) => v; case _ => player },
taskResolver,
tplayer,
msg.terminal_guid
)(item)
}
case Terminal.SellEquipment() =>
SellEquipmentFromInventory(tplayer, taskResolver, tplayer, msg.terminal_guid)(Player.FreeHandSlot)
SellEquipmentFromInventory(tplayer, tplayer, msg.terminal_guid)(Player.FreeHandSlot)
case Terminal.LearnCertification(cert) =>
avatarActor ! AvatarActor.LearnCertification(msg.terminal_guid, cert)
@ -2605,7 +2599,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
entry.obj.Faction = tplayer.Faction
vTrunk.InsertQuickly(entry.start, entry.obj)
})
taskResolver ! RegisterVehicleFromSpawnPad(vehicle, pad)
continent.tasks ! RegisterVehicleFromSpawnPad(vehicle, pad)
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, true))
}
case None =>
@ -2873,7 +2867,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
(old_weapons ++ old_inventory).foreach {
case (obj, guid) =>
sendResponse(ObjectDeleteMessage(guid, 0))
taskResolver ! GUIDTask.UnregisterEquipment(obj)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterEquipment(obj)(continent.GUID)
}
ApplyPurchaseTimersBeforePackingLoadout(player, vehicle, added_weapons ++ new_inventory)
} else if (accessedContainer.contains(target)) {
@ -3424,7 +3418,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
})
//load active players in zone (excepting players who are seated or players who are us)
val live = continent.LivePlayers
log.info(s"loading players ${live}")
log.info(s"loading players $live")
live
.filterNot(tplayer => {
tplayer.GUID == player.GUID || tplayer.VehicleSeated.nonEmpty
@ -3545,7 +3539,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
allActiveVehicles.collect {
case vehicle if vehicle.CargoHolds.nonEmpty =>
vehicle.CargoHolds.collect({
case (index, hold) if hold.isOccupied => {
case (index, hold: Cargo) if hold.isOccupied => {
CargoBehavior.CargoMountBehaviorForAll(
vehicle,
hold.Occupant.get,
@ -3580,7 +3574,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//implant terminals
continent.map.terminalToInterface.foreach({
case ((terminal_guid, interface_guid)) =>
case (terminal_guid, interface_guid) =>
val parent_guid = PlanetSideGUID(terminal_guid)
continent.GUID(interface_guid) match {
case Some(obj: Terminal) =>
@ -3617,7 +3611,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//base turrets
continent.map.turretToWeapon
.map { case ((turret_guid, _)) => continent.GUID(turret_guid) }
.map { case (turret_guid: Int, _) => continent.GUID(turret_guid) }
.collect {
case Some(turret: FacilityTurret) =>
val pguid = turret.GUID
@ -4112,7 +4106,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
CancelZoningProcessWithDescriptiveReason("cancel_use")
continent.GUID(player.VehicleSeated) match {
case Some(_) =>
RemoveOldEquipmentFromInventory(player, taskResolver)(item)
RemoveOldEquipmentFromInventory(player)(item)
case None =>
DropEquipmentFromInventory(player)(item)
}
@ -4159,9 +4153,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case x :: xs =>
val (deleteFunc, modifyFunc): (Equipment => Future[Any], (AmmoBox, Int) => Unit) = obj match {
case veh: Vehicle =>
(RemoveOldEquipmentFromInventory(veh, taskResolver), ModifyAmmunitionInVehicle(veh))
(RemoveOldEquipmentFromInventory(veh), ModifyAmmunitionInVehicle(veh))
case o: PlanetSideServerObject with Container =>
(RemoveOldEquipmentFromInventory(o, taskResolver), ModifyAmmunition(o))
(RemoveOldEquipmentFromInventory(o), ModifyAmmunition(o))
case _ =>
throw new Exception("ReloadMessage: should be a server object, not a regular game object")
}
@ -4329,7 +4323,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
continent.id,
AvatarAction.ProjectileExplodes(player.GUID, obj.GUID, obj)
)
taskResolver ! UnregisterProjectile(obj)
continent.tasks ! UnregisterProjectile(obj)
}
}
@ -4391,7 +4385,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
Some(destination: PlanetSideServerObject with Container),
Some(item: Equipment)
) =>
ContainableMoveItem(taskResolver, player.Name, source, destination, item, dest)
ContainableMoveItem(player.Name, source, destination, item, dest)
case (None, _, _) =>
log.error(s"MoveItem: wanted to move $item_guid from $source_guid, but could not find source object")
case (_, None, _) =>
@ -4428,7 +4422,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
destination.Fit(item)
) match {
case (Some((source, Some(_))), Some(dest)) =>
ContainableMoveItem(taskResolver, player.Name, source, destination, item, dest)
ContainableMoveItem(player.Name, source, destination, item, dest)
case (None, _) =>
log.error(s"LootItem: can not find where $item is put currently")
case (_, None) =>
@ -4659,7 +4653,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
)
)
sendResponse(ObjectDeleteMessage(kit.GUID, 0))
taskResolver ! GUIDTask.UnregisterEquipment(kit)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterEquipment(kit)(continent.GUID)
}
}
@ -5012,7 +5006,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case _ =>
GUIDTask.RegisterObjectTask(dObj)(continent.GUID)
}
taskResolver ! CallBackForTask(tasking, continent.Deployables, Zone.Deployable.Build(dObj, obj))
continent.tasks ! CallBackForTask(tasking, continent.Deployables, Zone.Deployable.Build(dObj, obj))
case Some(obj) =>
log.warn(s"DeployObject: $obj is something?")
@ -6277,9 +6271,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case x :: xs =>
val (deleteFunc, modifyFunc): (Equipment => Future[Any], (AmmoBox, Int) => Unit) = obj match {
case (veh: Vehicle) =>
(RemoveOldEquipmentFromInventory(veh, taskResolver), ModifyAmmunitionInVehicle(veh))
(RemoveOldEquipmentFromInventory(veh), ModifyAmmunitionInVehicle(veh))
case o: PlanetSideServerObject with Container =>
(RemoveOldEquipmentFromInventory(o, taskResolver), ModifyAmmunition(o))
(RemoveOldEquipmentFromInventory(o), ModifyAmmunition(o))
case _ =>
throw new Exception(
"PerformToolAmmoChange: (remove/modify) should be a server object, not a regular game object"
@ -6340,7 +6334,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
s"ChangeAmmo: taking ${originalBoxCapacity - splitReloadAmmo} from a box of ${originalBoxCapacity} $requestedAmmoType"
)
val boxForInventory = AmmoBox(box.Definition, splitReloadAmmo)
taskResolver ! stowNewFunc(boxForInventory)
continent.tasks ! stowNewFunc(boxForInventory)
fullMagazine
})
sendResponse(
@ -6385,10 +6379,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case Nil | List(_) => ; //done (the former case is technically not possible)
case _ :: xs =>
modifyFunc(previousBox, 0) //update to changed capacity value
xs.foreach(box => { taskResolver ! stowNewFunc(box) })
xs.foreach(box => { continent.tasks ! stowNewFunc(box) })
}
} else {
taskResolver ! GUIDTask.UnregisterObjectTask(previousBox)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterObjectTask(previousBox)(continent.GUID)
}
}
}
@ -6448,29 +6442,29 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
FindEquipmentStock(player, FindToolThatUses(ammoType), 3, CountGrenades).reverse match { //do not search sidearm holsters
case Nil =>
log.info(s"no more $ammoType grenades")
RemoveOldEquipmentFromInventory(player, taskResolver)(tool)
RemoveOldEquipmentFromInventory(player)(tool)
case x :: xs => //this is similar to ReloadMessage
val box = x.obj.asInstanceOf[Tool]
val tailReloadValue: Int = if (xs.isEmpty) { 0 }
else { xs.map(_.obj.asInstanceOf[Tool].Magazine).reduce(_ + _) }
val sumReloadValue: Int = box.Magazine + tailReloadValue
val actualReloadValue = (if (sumReloadValue <= 3) {
RemoveOldEquipmentFromInventory(player, taskResolver)(x.obj)
val actualReloadValue = if (sumReloadValue <= 3) {
RemoveOldEquipmentFromInventory(player)(x.obj)
sumReloadValue
} else {
ModifyAmmunition(player)(box.AmmoSlot.Box, 3 - tailReloadValue)
3
})
}
log.info(s"found $actualReloadValue more $ammoType grenades to throw")
ModifyAmmunition(player)(
tool.AmmoSlot.Box,
-actualReloadValue
) //grenade item already in holster (negative because empty)
xs.foreach(item => { RemoveOldEquipmentFromInventory(player, taskResolver)(item.obj) })
xs.foreach(item => { RemoveOldEquipmentFromInventory(player)(item.obj) })
}
} else if (tdef == GlobalDefinitions.phoenix) {
RemoveOldEquipmentFromInventory(player, taskResolver)(tool)
RemoveOldEquipmentFromInventory(player)(tool)
}
}
@ -6913,7 +6907,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
val zone = vehicle.PreviousGatingManifest().get.origin
zone.VehicleEvents ! VehicleServiceMessage(
zone.id,
VehicleAction.UnloadVehicle(player.GUID, zone, vehicle, vehicleToDelete)
VehicleAction.UnloadVehicle(player.GUID, vehicle, vehicleToDelete)
)
log.info(
s"AvatarCreate: cleaning up ghost of transitioning vehicle ${vehicle.Definition.Name}@${vehicleToDelete.guid} in zone ${zone.id}"
@ -7160,12 +7154,12 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
obj.Slot(4).Equipment match {
case None => ;
case Some(knife) =>
RemoveOldEquipmentFromInventory(obj, taskResolver)(knife)
RemoveOldEquipmentFromInventory(obj)(knife)
}
obj.Slot(0).Equipment match {
case Some(arms: Tool) =>
if (GlobalDefinitions.isMaxArms(arms.Definition)) {
RemoveOldEquipmentFromInventory(obj, taskResolver)(arms)
RemoveOldEquipmentFromInventory(obj)(arms)
}
case _ => ;
}
@ -7210,7 +7204,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
zone.Population ! Zone.Population.Release(avatar)
sendResponse(ObjectDeleteMessage(pguid, 0))
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(pguid, pguid, 0))
taskResolver ! GUIDTask.UnregisterPlayer(tplayer)(zone.GUID)
zone.tasks ! GUIDTask.UnregisterPlayer(tplayer)(zone.GUID)
}
}
@ -8077,7 +8071,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
*/
def CommonDestroyConstructionItem(tool: ConstructionItem, index: Int): Unit = {
if (SafelyRemoveConstructionItemFromSlot(tool, index, "CommonDestroyConstructionItem")) {
taskResolver ! GUIDTask.UnregisterEquipment(tool)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterEquipment(tool)(continent.GUID)
}
}
@ -8219,7 +8213,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
}) match {
case Some((parent, Some(slot))) =>
obj.Position = Vector3.Zero
RemoveOldEquipmentFromInventory(parent, taskResolver)(obj)
RemoveOldEquipmentFromInventory(parent)(obj)
log.info(s"RequestDestroy: equipment $obj")
true
@ -8414,7 +8408,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
if (!zoneReload && zoneId == continent.id) {
if (player.isBackpack) { // important! test the actor-wide player ref, not the parameter
// respawning from unregistered player
taskResolver ! RegisterAvatar(targetPlayer)
continent.tasks ! RegisterAvatar(targetPlayer)
} else {
// move existing player; this is the one case where the original GUID is retained by the player
self ! PlayerLoaded(targetPlayer)
@ -8517,7 +8511,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
if (!zoneReload && zoneId == continent.id) {
if (vehicle.Definition == GlobalDefinitions.droppod) {
//instant action droppod in the same zone
taskResolver ! RegisterDroppod(vehicle, player)
continent.tasks ! RegisterDroppod(vehicle, player)
} else {
//transferring a vehicle between spawn points (warp gates) in the same zone
self ! PlayerLoaded(player)
@ -8541,7 +8535,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
//do not delete if vehicle has passengers or cargo
continent.VehicleEvents ! VehicleServiceMessage(
continent.id,
VehicleAction.UnloadVehicle(pguid, continent, vehicle, topLevel)
VehicleAction.UnloadVehicle(pguid, vehicle, topLevel)
)
None
} else {
@ -8640,7 +8634,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
task: TaskResolver.GiveTask,
zoneMessage: InterstellarClusterService.FindZone
): Unit = {
taskResolver ! TaskResolver.GiveTask(
continent.tasks ! TaskResolver.GiveTask(
new Task() {
override def isComplete: Task.Resolution.Value = task.task.isComplete
@ -8671,7 +8665,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
avatarActor ! AvatarActor.SetVehicle(None)
}
RemoveBoomerTriggersFromInventory().foreach(obj => {
taskResolver ! GUIDTask.UnregisterObjectTask(obj)(continent.GUID)
continent.tasks ! GUIDTask.UnregisterObjectTask(obj)(continent.GUID)
})
Deployables.Disown(continent, avatar, self)
drawDeloyableIcon = RedrawDeployableIcons //important for when SetCurrentAvatar initializes the UI next zone
@ -9149,7 +9143,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
continent.id,
AvatarAction.ProjectileExplodes(player.GUID, projectile_guid, projectile)
)
taskResolver ! UnregisterProjectile(projectile)
continent.tasks ! UnregisterProjectile(projectile)
projectiles(local_index) match {
case Some(obj) if !obj.isResolved => obj.Miss()
case _ => ;
@ -9185,7 +9179,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
tplayer.VehicleSeated = None
zone.Population ! Zone.Population.Release(avatar)
sendResponse(ObjectDeleteMessage(tplayer.GUID, 0))
taskResolver ! GUIDTask.UnregisterPlayer(tplayer)(zone.GUID)
zone.tasks ! GUIDTask.UnregisterPlayer(tplayer)(zone.GUID)
}
}
@ -9374,7 +9368,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
log.trace(
s"WeaponFireMessage: ${projectile_info.Name} is a remote projectile"
)
taskResolver ! (if (projectile.HasGUID) {
continent.tasks ! (if (projectile.HasGUID) {
continent.AvatarEvents ! AvatarServiceMessage(
continent.id,
AvatarAction.ProjectileExplodes(

View file

@ -118,22 +118,19 @@ object WorldSession {
* @see `tell`
* @see `Zone.AvatarEvents`
* @param obj the container
* @param taskResolver na
* @param item the item being manipulated
* @param slot na
* @return a `Future` that anticipates the resolution to this manipulation
*/
def PutEquipmentInInventorySlot(
obj: PlanetSideServerObject with Container,
taskResolver: ActorRef
obj: PlanetSideServerObject with Container
)(item: Equipment, slot: Int): Future[Any] = {
val localContainer = obj
val localItem = item
val localResolver = taskResolver
val result = ask(localContainer.Actor, Containable.PutItemInSlotOnly(localItem, slot))
result.onComplete {
case Failure(_) | Success(_: Containable.CanNotPutItemInSlot) =>
localResolver ! GUIDTask.UnregisterEquipment(localItem)(localContainer.Zone.GUID)
localContainer.Zone.tasks ! GUIDTask.UnregisterEquipment(localItem)(localContainer.Zone.GUID)
case _ => ;
}
result
@ -150,14 +147,12 @@ object WorldSession {
* @see `Task`
* @see `TaskResolver.GiveTask`
* @param obj the container
* @param taskResolver na
* @param item the item being manipulated
* @param slot where the item will be placed in the container
* @return a `TaskResolver` object
*/
def PutLoadoutEquipmentInInventory(
obj: PlanetSideServerObject with Container,
taskResolver: ActorRef
obj: PlanetSideServerObject with Container
)(item: Equipment, slot: Int): TaskResolver.GiveTask = {
val localZone = obj.Zone
TaskResolver.GiveTask(
@ -165,7 +160,7 @@ object WorldSession {
private val localContainer = obj
private val localItem = item
private val localSlot = slot
private val localFunc: (Equipment, Int) => Future[Any] = PutEquipmentInInventorySlot(obj, taskResolver)
private val localFunc: (Equipment, Int) => Future[Any] = PutEquipmentInInventorySlot(obj)
override def Timeout: Long = 1000
@ -203,7 +198,6 @@ object WorldSession {
* @see `PutEquipmentInInventorySlot`
* @see `TerminalMessageOnTimeout`
* @param obj the container
* @param taskResolver na
* @param player na
* @param term na
* @param item the item being manipulated
@ -211,7 +205,6 @@ object WorldSession {
*/
def BuyNewEquipmentPutInInventory(
obj: PlanetSideServerObject with Container,
taskResolver: ActorRef,
player: Player,
term: PlanetSideGUID
)(item: Equipment): TaskResolver.GiveTask = {
@ -221,7 +214,6 @@ object WorldSession {
private val localContainer = obj
private val localItem = item
private val localPlayer = player
private val localResolver = taskResolver
private val localTermMsg: Boolean => Unit = TerminalResult(term, localPlayer, TransactionType.Buy)
override def Timeout: Long = 1000
@ -242,7 +234,7 @@ object WorldSession {
case Failure(_) | Success(_: Containable.CanNotPutItemInSlot) =>
if (localContainer != localPlayer) {
TerminalMessageOnTimeout(
PutEquipmentInInventorySlot(localPlayer, localResolver)(localItem, Player.FreeHandSlot),
PutEquipmentInInventorySlot(localPlayer)(localItem, Player.FreeHandSlot),
localTermMsg
)
.onComplete {
@ -252,7 +244,7 @@ object WorldSession {
localTermMsg(true)
}
} else {
localResolver ! GUIDTask.UnregisterEquipment(localItem)(localContainer.Zone.GUID)
localContainer.Zone.tasks ! GUIDTask.UnregisterEquipment(localItem)(localContainer.Zone.GUID)
localTermMsg(false)
}
case _ =>
@ -289,12 +281,11 @@ object WorldSession {
* @see `TaskResolver.GiveTask`
* @see `Zone.AvatarEvents`
* @param player the player whose visible slot will be equipped and drawn
* @param taskResolver na
* @param item the item to equip
* @param slot the slot in which the item will be equipped
* @return a `TaskResolver` object
*/
def HoldNewEquipmentUp(player: Player, taskResolver: ActorRef)(item: Equipment, slot: Int): TaskResolver.GiveTask = {
def HoldNewEquipmentUp(player: Player)(item: Equipment, slot: Int): TaskResolver.GiveTask = {
if (player.VisibleSlots.contains(slot)) {
val localZone = player.Zone
TaskResolver.GiveTask(
@ -303,7 +294,6 @@ object WorldSession {
private val localGUID = player.GUID
private val localItem = item
private val localSlot = slot
private val localResolver = taskResolver
override def Timeout: Long = 1000
@ -318,7 +308,7 @@ object WorldSession {
ask(localPlayer.Actor, Containable.PutItemInSlotOnly(localItem, localSlot))
.onComplete {
case Failure(_) | Success(_: Containable.CanNotPutItemInSlot) =>
localResolver ! GUIDTask.UnregisterEquipment(localItem)(localZone.GUID)
localPlayer.Zone.tasks ! GUIDTask.UnregisterEquipment(localItem)(localZone.GUID)
case _ =>
if (localPlayer.DrawnSlot != Player.HandsDownSlot) {
localPlayer.DrawnSlot = Player.HandsDownSlot
@ -438,20 +428,18 @@ object WorldSession {
* @see `GUIDTask.UnregisterEquipment`
* @see `Zone.AvatarEvents`
* @param obj the container to search
* @param taskResolver na
* @param item the item to find and remove from the container
* @return a `Future` that anticipates the resolution to this manipulation
*/
def RemoveOldEquipmentFromInventory(obj: PlanetSideServerObject with Container, taskResolver: ActorRef)(
def RemoveOldEquipmentFromInventory(obj: PlanetSideServerObject with Container)(
item: Equipment
): Future[Any] = {
val localContainer = obj
val localItem = item
val localResolver = taskResolver
val result = ask(localContainer.Actor, Containable.RemoveItemFromSlot(localItem))
result.onComplete {
case Success(Containable.ItemFromSlot(_, Some(_), Some(_))) =>
localResolver ! GUIDTask.UnregisterEquipment(localItem)(localContainer.Zone.GUID)
localContainer.Zone.tasks ! GUIDTask.UnregisterEquipment(localItem)(localContainer.Zone.GUID)
case _ =>
}
result
@ -474,7 +462,6 @@ object WorldSession {
* @see `TerminalMessageOnTimeout`
* @see `TerminalResult`
* @param obj the container to search
* @param taskResolver na
* @param player the player who used the terminal
* @param term the unique identifier number of the terminal
* @param slot from which slot the equipment is to be removed
@ -482,14 +469,12 @@ object WorldSession {
*/
def SellEquipmentFromInventory(
obj: PlanetSideServerObject with Container,
taskResolver: ActorRef,
player: Player,
term: PlanetSideGUID
)(slot: Int): Future[Any] = {
val localContainer = obj
val localPlayer = player
val localSlot = slot
val localResolver = taskResolver
val localTermMsg: Boolean => Unit = TerminalResult(term, localPlayer, TransactionType.Sell)
val result = TerminalMessageOnTimeout(
ask(localContainer.Actor, Containable.RemoveItemFromSlot(localSlot)),
@ -497,7 +482,7 @@ object WorldSession {
)
result.onComplete {
case Success(Containable.ItemFromSlot(_, Some(item), Some(_))) =>
localResolver ! GUIDTask.UnregisterEquipment(item)(localContainer.Zone.GUID)
localContainer.Zone.tasks ! GUIDTask.UnregisterEquipment(item)(localContainer.Zone.GUID)
localTermMsg(true)
case _ =>
localTermMsg(false)
@ -519,7 +504,6 @@ object WorldSession {
* @see `RemoveEquipmentFromLockerContainer`
* @see `StowEquipmentInLockerContainer`
* @see `TaskResolver`
* @param taskResolver na
* @param toChannel broadcast channel name for a manual packet callback
* @param source the container in which the item is to be removed
* @param destination the container into which the item is to be placed
@ -527,7 +511,6 @@ object WorldSession {
* @param dest where in the destination container the item is being placed
*/
def ContainableMoveItem(
taskResolver: ActorRef,
toChannel: String,
source: PlanetSideServerObject with Container,
destination: PlanetSideServerObject with Container,
@ -536,9 +519,9 @@ object WorldSession {
) : Unit = {
(source, destination) match {
case (locker: LockerContainer, _) if !destination.isInstanceOf[LockerContainer] =>
RemoveEquipmentFromLockerContainer(taskResolver, toChannel, locker, destination, item, dest)
RemoveEquipmentFromLockerContainer(toChannel, locker, destination, item, dest)
case (_, locker: LockerContainer) =>
StowEquipmentInLockerContainer(taskResolver, toChannel, source, locker, item, dest)
StowEquipmentInLockerContainer(toChannel, source, locker, item, dest)
case _ =>
source.Actor ! Containable.MoveItem(destination, item, dest)
}
@ -564,7 +547,6 @@ object WorldSession {
* @see `TaskResolver`
* @see `TaskResolver.GiveTask`
* @see `Zone.AvatarEvents`
* @param taskResolver na
* @param toChannel broadcast channel name for a manual packet callback
* @param source the container in which the item is to be removed
* @param destination the container into which the item is to be placed
@ -572,7 +554,6 @@ object WorldSession {
* @param dest where in the destination container the item is being placed
*/
def StowEquipmentInLockerContainer(
taskResolver: ActorRef,
toChannel: String,
source: PlanetSideServerObject with Container,
destination: PlanetSideServerObject with Container,
@ -605,7 +586,7 @@ object WorldSession {
//too many swap items or other error; this attempt will probably fail
(Nil, None)
}
taskResolver ! TaskResolver.GiveTask(
destination.Zone.tasks ! TaskResolver.GiveTask(
new Task() {
val localGUID = swapItemGUID //the swap item's original GUID, if any swap item
val localChannel = toChannel
@ -659,7 +640,6 @@ object WorldSession {
* @see `TaskResolver`
* @see `TaskResolver.GiveTask`
* @see `Zone.AvatarEvents`
* @param taskResolver na
* @param toChannel broadcast channel name for a manual packet callback
* @param source the container in which the item is to be removed
* @param destination the container into which the item is to be placed
@ -667,14 +647,13 @@ object WorldSession {
* @param dest where in the destination container the item is being placed
*/
def RemoveEquipmentFromLockerContainer(
taskResolver: ActorRef,
toChannel: String,
source: PlanetSideServerObject with Container,
destination: PlanetSideServerObject with Container,
item: Equipment,
dest: Int
): Unit = {
taskResolver ! TaskResolver.GiveTask(
destination.Zone.tasks ! TaskResolver.GiveTask(
new Task() {
val localGUID = item.GUID //original GUID
val localChannel = toChannel

View file

@ -2,12 +2,11 @@
package net.psforever.objects.serverobject.pad
import akka.actor.{ActorContext, Cancellable, Props}
import net.psforever.objects.guid.GUIDTask.UnregisterVehicle
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
import net.psforever.objects.serverobject.pad.process.{VehicleSpawnControlBase, VehicleSpawnControlConcealPlayer}
import net.psforever.objects.zones.Zone
import net.psforever.objects.{Default, Player, Vehicle}
import net.psforever.services.RemoverActor
import net.psforever.services.vehicle.VehicleServiceMessage
import scala.annotation.tailrec
import scala.concurrent.ExecutionContext.Implicits.global
@ -330,7 +329,7 @@ object VehicleSpawnControl {
if (zone.Vehicles.exists(_.GUID == vehicle.GUID)) { //already added to zone
vehicle.Actor ! Vehicle.Deconstruct()
} else { //just registered to zone
zone.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.AddTask(vehicle, zone, Some(0 seconds)))
zone.tasks ! UnregisterVehicle(vehicle)(zone.GUID)
}
}
}

View file

@ -6,6 +6,7 @@ import net.psforever.objects._
import net.psforever.objects.ballistics.{ResolvedProjectile, VehicleSource}
import net.psforever.objects.ce.TelepadLike
import net.psforever.objects.equipment.{Equipment, EquipmentSlot, JammableMountedWeapons}
import net.psforever.objects.guid.GUIDTask
import net.psforever.objects.inventory.{GridInventory, InventoryItem}
import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
@ -20,7 +21,6 @@ import net.psforever.objects.serverobject.repair.RepairableVehicle
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.vital.VehicleShieldCharge
import net.psforever.objects.zones.Zone
import net.psforever.services.RemoverActor
import net.psforever.packet.game._
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
import net.psforever.types.{DriveState, ExoSuitType, PlanetSideGUID, Vector3}
@ -338,7 +338,7 @@ class VehicleControl(vehicle: Vehicle)
}
})
//unregister
events ! VehicleServiceMessage.Decon(RemoverActor.AddTask(vehicle, zone, Some(0 seconds)))
zone.tasks ! GUIDTask.UnregisterVehicle(vehicle)(zone.GUID)
//banished to the shadow realm
vehicle.Position = Vector3.Zero
//queue final deletion
@ -355,7 +355,7 @@ class VehicleControl(vehicle: Vehicle)
val zone = vehicle.Zone
zone.VehicleEvents ! VehicleServiceMessage(
zone.id,
VehicleAction.UnloadVehicle(Service.defaultPlayerGUID, zone, vehicle, vehicle.GUID)
VehicleAction.UnloadVehicle(Service.defaultPlayerGUID, vehicle, vehicle.GUID)
)
zone.Transport ! Zone.Vehicle.Despawn(vehicle)
case _ =>

View file

@ -8,7 +8,7 @@ import net.psforever.objects._
import net.psforever.objects.ce.Deployable
import net.psforever.objects.entity.IdentifiableEntity
import net.psforever.objects.equipment.Equipment
import net.psforever.objects.guid.NumberPoolHub
import net.psforever.objects.guid.{NumberPoolHub, TaskResolver}
import net.psforever.objects.guid.actor.UniqueNumberSystem
import net.psforever.objects.guid.key.LoanedKey
import net.psforever.objects.guid.selector.RandomSelector
@ -85,6 +85,8 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
/** Used by the `Zone` to coordinate `Equipment` dropping and collection requests. */
private var ground: ActorRef = Default.Actor
private var taskResolver: ActorRef = Default.Actor
/**
*/
private val constructions: ListBuffer[PlanetSideGameObject with Deployable] = ListBuffer()
@ -167,6 +169,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
def init(implicit context: ActorContext): Unit = {
if (accessor == ActorRef.noSender) {
SetupNumberPools()
taskResolver = CreateTaskResolvers(context)
accessor = context.actorOf(
RandomPool(25).props(
Props(classOf[UniqueNumberSystem], this.guid, UniqueNumberSystem.AllocateNumberPoolActors(this.guid))
@ -790,6 +793,12 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
vehicleEvents = bus
VehicleEvents
}
def tasks: ActorRef = taskResolver
protected def CreateTaskResolvers(context: ActorContext, numberCreated: Int = 20): ActorRef = {
context.actorOf(RandomPool(numberCreated).props(Props[TaskResolver]()), s"zone-$id-taskResolver")
}
}
object Zone {

View file

@ -30,7 +30,7 @@ import scala.util.Success
* and finally unregistering it.
* Some types of object have (de-)implementation variations which should be made explicit through the overrides.
*/
abstract class RemoverActor extends SupportActor[RemoverActor.Entry] {
abstract class RemoverActor(val taskResolver: ActorRef) extends SupportActor[RemoverActor.Entry] {
/**
* The timer that checks whether entries in the first pool are still eligible for that pool.
@ -52,24 +52,12 @@ abstract class RemoverActor extends SupportActor[RemoverActor.Entry] {
*/
var secondHeap: List[RemoverActor.Entry] = List()
protected var taskResolver: ActorRef = ActorRef.noSender
val sameEntryComparator = new SimilarityComparator[RemoverActor.Entry]() {
def Test(entry1: RemoverActor.Entry, entry2: RemoverActor.Entry): Boolean = {
entry1.obj == entry2.obj && entry1.zone == entry2.zone && entry1.obj.GUID == entry2.obj.GUID
}
}
/**
* Send the initial message that requests a task resolver for assisting in the removal process.
*/
override def preStart(): Unit = {
super.preStart()
ServiceManager.serviceManager ! ServiceManager.Lookup(
"taskResolver"
) //ask for a resolver to deal with the GUID system
}
/**
* Sufficiently clean up the current contents of these waiting removal jobs.
* Cancel all timers, rush all entries in the lists through their individual steps, then empty the lists.
@ -88,19 +76,9 @@ abstract class RemoverActor extends SupportActor[RemoverActor.Entry] {
}
firstHeap = Nil
secondHeap = Nil
taskResolver = ActorRef.noSender
}
def receive: Receive = {
case ServiceManager.LookupResult("taskResolver", endpoint) =>
taskResolver = endpoint
context.become(Processing)
case msg =>
debug(s"received message $msg before being properly initialized")
}
def Processing: Receive =
def receive: Receive =
entryManagementBehaviors
.orElse {
case RemoverActor.AddTask(obj, zone, duration) =>

View file

@ -49,9 +49,6 @@ class AccountPersistenceService extends Actor {
/** squad service event hook */
var squad: ActorRef = ActorRef.noSender
/** task resolver service event hook */
var resolver: ActorRef = ActorRef.noSender
/** log, for trace and warnings only */
val log = org.log4s.getLogger
@ -62,7 +59,6 @@ class AccountPersistenceService extends Actor {
*/
override def preStart(): Unit = {
ServiceManager.serviceManager ! ServiceManager.Lookup("squad")
ServiceManager.serviceManager ! ServiceManager.Lookup("taskResolver")
log.trace("Awaiting system service hooks ...")
}
@ -130,17 +126,9 @@ class AccountPersistenceService extends Actor {
* @see `ServiceManager.LookupResult`
*/
val Setup: Receive = {
case ServiceManager.LookupResult(id, endpoint) =>
id match {
case "squad" =>
squad = endpoint
case "taskResolver" =>
resolver = endpoint
}
if (
squad != ActorRef.noSender &&
resolver != ActorRef.noSender
) {
case ServiceManager.LookupResult("squad", endpoint) =>
squad = endpoint
if (squad != ActorRef.noSender) {
log.trace("Service hooks obtained. Continuing with standard operation.")
context.become(Started)
}
@ -156,7 +144,7 @@ class AccountPersistenceService extends Actor {
*/
def CreateNewPlayerToken(name: String): ActorRef = {
val ref =
context.actorOf(Props(classOf[PersistenceMonitor], name, squad, resolver), s"$name-${NextPlayerIndex(name)}")
context.actorOf(Props(classOf[PersistenceMonitor], name, squad), s"$name-${NextPlayerIndex(name)}")
accounts += name -> ref
ref
}
@ -231,10 +219,8 @@ object AccountPersistenceService {
* and to determine the conditions for end-of-life activity.
* @param name the unique name of the player
* @param squadService a hook into the `SquadService` event system
* @param taskResolver a hook into the `TaskResolver` event system;
* used for object unregistering
*/
class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: ActorRef) extends Actor {
class PersistenceMonitor(name: String, squadService: ActorRef) extends Actor {
/** the last-reported zone of this player */
var inZone: Zone = Zone.Nowhere
@ -404,7 +390,7 @@ class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: Act
}
inZone.Population.tell(Zone.Population.Release(avatar), parent)
inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, AvatarAction.ObjectDelete(pguid, pguid)), parent)
taskResolver.tell(GUIDTask.UnregisterPlayer(player)(inZone.GUID), parent)
inZone.tasks.tell(GUIDTask.UnregisterPlayer(player)(inZone.GUID), parent)
AvatarLogout(avatar)
}
@ -423,7 +409,7 @@ class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: Act
squadService.tell(Service.Leave(Some(avatar.id.toString)), context.parent)
Deployables.Disown(inZone, avatar, context.parent)
inZone.Population.tell(Zone.Population.Leave(avatar), context.parent)
taskResolver.tell(GUIDTask.UnregisterObjectTask(avatar.locker)(inZone.GUID), context.parent)
inZone.tasks.tell(GUIDTask.UnregisterObjectTask(avatar.locker)(inZone.GUID), context.parent)
log.info(s"logout of ${avatar.name}")
}
}

View file

@ -10,8 +10,8 @@ import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRem
import net.psforever.services.{GenericEventBus, RemoverActor, Service}
class AvatarService(zone: Zone) extends Actor {
private val undertaker: ActorRef = context.actorOf(Props[CorpseRemovalActor](), s"${zone.id}-corpse-removal-agent")
private val janitor = context.actorOf(Props[DroppedItemRemover](), s"${zone.id}-item-remover-agent")
private val undertaker: ActorRef = context.actorOf(Props(classOf[CorpseRemovalActor], zone.tasks), s"${zone.id}-corpse-removal-agent")
private val janitor = context.actorOf(Props(classOf[DroppedItemRemover], zone.tasks), s"${zone.id}-item-remover-agent")
private[this] val log = org.log4s.getLogger

View file

@ -1,6 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.services.avatar.support
import akka.actor.ActorRef
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
import net.psforever.objects.Player
import net.psforever.types.ExoSuitType
@ -9,7 +10,7 @@ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import scala.concurrent.duration._
class CorpseRemovalActor extends RemoverActor {
class CorpseRemovalActor(taskResolver: ActorRef) extends RemoverActor(taskResolver) {
final val FirstStandardDuration: FiniteDuration = 1 minute
final val SecondStandardDuration: FiniteDuration = 500 milliseconds

View file

@ -1,6 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.services.avatar.support
import akka.actor.ActorRef
import net.psforever.objects.equipment.Equipment
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
import net.psforever.services.{RemoverActor, Service}
@ -8,7 +9,7 @@ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import scala.concurrent.duration._
class DroppedItemRemover extends RemoverActor {
class DroppedItemRemover(taskResolver: ActorRef) extends RemoverActor(taskResolver) {
final val FirstStandardDuration: FiniteDuration = 3 minutes
final val SecondStandardDuration: FiniteDuration = 500 milliseconds

View file

@ -26,7 +26,7 @@ class LocalService(zone: Zone) extends Actor {
private val doorCloser = context.actorOf(Props[DoorCloseActor](), s"${zone.id}-local-door-closer")
private val hackClearer = context.actorOf(Props[HackClearActor](), s"${zone.id}-local-hack-clearer")
private val hackCapturer = context.actorOf(Props[HackCaptureActor](), s"${zone.id}-local-hack-capturer")
private val engineer = context.actorOf(Props[DeployableRemover](), s"${zone.id}-deployable-remover-agent")
private val engineer = context.actorOf(Props(classOf[DeployableRemover], zone.tasks), s"${zone.id}-deployable-remover-agent")
private val teleportDeployment: ActorRef =
context.actorOf(Props[RouterTelepadActivation](), s"${zone.id}-telepad-activate-agent")
private[this] val log = org.log4s.getLogger

View file

@ -1,6 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.services.local.support
import akka.actor.ActorRef
import net.psforever.objects.ce.Deployable
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
import net.psforever.objects.zones.Zone
@ -10,7 +11,7 @@ import net.psforever.services.RemoverActor
import scala.concurrent.duration._
class DeployableRemover extends RemoverActor {
class DeployableRemover(taskResolver: ActorRef) extends RemoverActor(taskResolver) {
final val FirstStandardDuration: FiniteDuration = 3 minutes
final val SecondStandardDuration: FiniteDuration = 2 seconds
@ -64,7 +65,7 @@ class DeployableRemover extends RemoverActor {
boomer.Trigger match {
case Some(trigger) =>
boomer.Trigger = None
taskResolver ! GUIDTask.UnregisterObjectTask(trigger)(entry.zone.GUID)
boomer.Zone.tasks ! GUIDTask.UnregisterObjectTask(trigger)(entry.zone.GUID)
case None => ;
}
GUIDTask.UnregisterObjectTask(boomer)(entry.zone.GUID)

View file

@ -10,12 +10,11 @@ import net.psforever.objects.vital.RepairFromTerm
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.ObjectCreateMessage
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
import net.psforever.services.vehicle.support.{TurretUpgrader, VehicleRemover}
import net.psforever.services.vehicle.support.TurretUpgrader
import net.psforever.types.{DriveState, PlanetSideGUID}
import net.psforever.services.{GenericEventBus, RemoverActor, Service}
import net.psforever.services.{GenericEventBus, Service}
class VehicleService(zone: Zone) extends Actor {
private val vehicleDecon: ActorRef = context.actorOf(Props[VehicleRemover](), s"${zone.id}-vehicle-decon-agent")
private val turretUpgrade: ActorRef = context.actorOf(Props[TurretUpgrader](), s"${zone.id}-turret-upgrade-agent")
private[this] val log = org.log4s.getLogger
@ -157,8 +156,7 @@ class VehicleService(zone: Zone) extends Actor {
)
)
)
case VehicleAction.UnloadVehicle(player_guid, continent, vehicle, vehicle_guid) =>
vehicleDecon ! RemoverActor.ClearSpecific(List(vehicle), continent) //precaution
case VehicleAction.UnloadVehicle(player_guid, vehicle, vehicle_guid) =>
VehicleEvents.publish(
VehicleServiceResponse(
s"/$forChannel/Vehicle",
@ -246,10 +244,6 @@ class VehicleService(zone: Zone) extends Actor {
case _ => ;
}
//message to VehicleRemover
case VehicleServiceMessage.Decon(msg) =>
vehicleDecon forward msg
//message to TurretUpgrader
case VehicleServiceMessage.TurretUpgrade(msg) =>
turretUpgrade forward msg

View file

@ -15,8 +15,6 @@ object VehicleServiceMessage {
final case class GiveActorControl(vehicle: Vehicle, actorName: String)
final case class RevokeActorControl(vehicle: Vehicle)
final case class Decon(msg: Any)
final case class TurretUpgrade(msg: Any)
final case class AMSDeploymentChange(zone: Zone)
@ -83,7 +81,6 @@ object VehicleAction {
extends Action
final case class UnloadVehicle(
player_guid: PlanetSideGUID,
continent: Zone,
vehicle: Vehicle,
vehicle_guid: PlanetSideGUID
) extends Action

View file

@ -2,6 +2,7 @@
package net.psforever.services.vehicle.support
import akka.actor.{ActorRef, Cancellable}
import net.psforever.objects.equipment.EquipmentSlot
import net.psforever.objects.{AmmoBox, Default, PlanetSideGameObject, Tool}
import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver}
import net.psforever.objects.serverobject.PlanetSideServerObject
@ -11,7 +12,6 @@ import net.psforever.objects.zones.Zone
import net.psforever.types.PlanetSideGUID
import net.psforever.services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import net.psforever.services.{Service, ServiceManager}
import scala.concurrent.duration._
import scala.util.Success
@ -21,22 +21,12 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
var list: List[TurretUpgrader.Entry] = List()
private var taskResolver: ActorRef = ActorRef.noSender
val sameEntryComparator = new SimilarityComparator[TurretUpgrader.Entry]() {
def Test(entry1: TurretUpgrader.Entry, entry2: TurretUpgrader.Entry): Boolean = {
entry1.obj == entry2.obj && entry1.zone == entry2.zone && entry1.obj.GUID == entry2.obj.GUID
}
}
/**
* Send the initial message that requests a task resolver for assisting in the removal process.
*/
override def preStart(): Unit = {
super.preStart()
self ! Service.Startup()
}
/**
* Sufficiently clean up the current contents of these waiting removal jobs.
* Cancel all timers, rush all entries in the lists through their individual steps, then empty the lists.
@ -49,7 +39,6 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
UpgradeTurretAmmo
}
list = Nil
taskResolver = ActorRef.noSender
}
def CreateEntry(obj: PlanetSideGameObject, zone: Zone, upgrade: TurretUpgrade.Value, duration: Long) =
@ -57,21 +46,7 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
def InclusionTest(entry: TurretUpgrader.Entry): Boolean = entry.obj.isInstanceOf[FacilityTurret]
def receive: Receive = {
case Service.Startup() =>
ServiceManager.serviceManager ! ServiceManager.Lookup(
"taskResolver"
) //ask for a resolver to deal with the GUID system
case ServiceManager.LookupResult("taskResolver", endpoint) =>
taskResolver = endpoint
context.become(Processing)
case msg =>
debug(s"received message $msg before being properly initialized")
}
def Processing: Receive =
def receive: Receive =
entryManagementBehaviors
.orElse {
case TurretUpgrader.AddTask(turret, zone, upgrade, duration) =>
@ -219,7 +194,7 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
.map(box => GUIDTask.RegisterEquipment(box)(guid))
.toList
)
taskResolver ! TaskResolver.GiveTask(
target.Zone.tasks ! TaskResolver.GiveTask(
new Task() {
private val tasks = oldBoxesTask
@ -258,7 +233,7 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
val targetGUID = target.GUID
if (target.Health > 0) {
target.Weapons
.map({ case (index, slot) => (index, slot.Equipment) })
.map({ case (index: Int, slot: EquipmentSlot) => (index, slot.Equipment) })
.collect {
case (index, Some(tool: Tool)) =>
context.parent ! VehicleServiceMessage(

View file

@ -1,33 +0,0 @@
// Copyright (c) 2017-2020 PSForever
package net.psforever.services.vehicle.support
import akka.actor.{Actor, ActorRef}
import net.psforever.objects.Vehicle
import net.psforever.objects.guid.GUIDTask.UnregisterVehicle
import net.psforever.services.{RemoverActor, ServiceManager}
class VehicleRemover extends Actor {
var taskResolver: ActorRef = ActorRef.noSender
override def preStart(): Unit = {
super.preStart()
ServiceManager.serviceManager ! ServiceManager.Lookup(
"taskResolver"
) //ask for a resolver to deal with the GUID system
}
def receive: Receive = {
case ServiceManager.LookupResult("taskResolver", endpoint) =>
taskResolver = endpoint
context.become(Processing)
case _ => ;
}
def Processing: Receive = {
case RemoverActor.AddTask(obj: Vehicle, zone, _) =>
taskResolver ! UnregisterVehicle(obj)(zone.GUID)
case _ => ;
}
}

View file

@ -16,11 +16,13 @@ import net.psforever.objects.vital.Vitality
import net.psforever.objects.vital.damage.DamageProfile
import net.psforever.objects.zones.{Zone, ZoneMap}
import net.psforever.objects.{GlobalDefinitions, Player, Tool}
import net.psforever.services.ServiceManager
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3}
import scala.concurrent.duration._
class AutoRepairRequestNtuTest extends FreedContextActorTest {
ServiceManager.boot
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.Spawn()
val weapon = new Tool(GlobalDefinitions.suppressor)
@ -80,6 +82,7 @@ class AutoRepairRequestNtuTest extends FreedContextActorTest {
}
class AutoRepairRequestNtuRepeatTest extends FreedContextActorTest {
ServiceManager.boot
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.Spawn()
val weapon = new Tool(GlobalDefinitions.suppressor)
@ -141,6 +144,7 @@ class AutoRepairRequestNtuRepeatTest extends FreedContextActorTest {
}
class AutoRepairNoRequestNtuTest extends FreedContextActorTest {
ServiceManager.boot
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.Spawn()
val weapon = new Tool(GlobalDefinitions.suppressor)
@ -195,6 +199,7 @@ class AutoRepairNoRequestNtuTest extends FreedContextActorTest {
}
class AutoRepairRestoreRequestNtuTest extends FreedContextActorTest {
ServiceManager.boot
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.Spawn()
val weapon = new Tool(GlobalDefinitions.suppressor)
@ -258,6 +263,7 @@ class AutoRepairRestoreRequestNtuTest extends FreedContextActorTest {
}
class AutoRepairRepairWithNtuTest extends FreedContextActorTest {
ServiceManager.boot
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.Spawn()
val weapon = new Tool(GlobalDefinitions.suppressor)
@ -316,6 +322,7 @@ class AutoRepairRepairWithNtuTest extends FreedContextActorTest {
}
class AutoRepairRepairWithNtuUntilDoneTest extends FreedContextActorTest {
ServiceManager.boot
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
player.Spawn()
val weapon = new Tool(GlobalDefinitions.suppressor)

View file

@ -2,11 +2,10 @@
package objects
import akka.actor.{Actor, Props}
import akka.routing.RandomPool
import akka.testkit.TestProbe
import base.ActorTest
import net.psforever.actors.zone.{BuildingActor, ZoneActor}
import net.psforever.objects.guid.{NumberPoolHub, TaskResolver}
import net.psforever.objects.guid.NumberPoolHub
import net.psforever.objects.guid.source.MaxNumberSource
import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.{GlobalDefinitions, Ntu, Player, Vehicle}
@ -17,7 +16,6 @@ import net.psforever.objects.zones.{Zone, ZoneMap}
import net.psforever.packet.game.UseItemMessage
import net.psforever.types._
import org.specs2.mutable.Specification
import net.psforever.services.ServiceManager
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import akka.actor.typed.scaladsl.adapter._
import net.psforever.objects.avatar.Avatar
@ -77,18 +75,21 @@ class ResourceSiloTest extends Specification {
}
class ResourceSiloControlStartupTest extends ActorTest {
val serviceManager = ServiceManager.boot(system)
serviceManager ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]()), "taskResolver")
val obj = ResourceSilo()
obj.GUID = PlanetSideGUID(1)
val probe = TestProbe()
serviceManager ! ServiceManager.Register(Props(classOf[ResourceSiloTest.ProbedAvatarService], probe), "avatar")
obj.Actor = system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo")
val zone = new Zone("nowhere", new ZoneMap("nowhere-map"), 0)
val buildingEvents = TestProbe("test-building-events")
obj.Owner =
new Building("Building", building_guid = 6, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building) {
Actor = buildingEvents.ref
}
obj.Owner.GUID = PlanetSideGUID(6)
"Resource silo" should {
"startup properly" in {
expectNoMessage(500 milliseconds)
system.actorOf(Props(classOf[ResourceSiloControl], obj), "test-silo") ! "startup"
expectNoMessage(1 seconds)
obj.Actor ! "startup"
expectNoMessage(max = 1000 milliseconds)
}
}
}

View file

@ -15,7 +15,7 @@ import net.psforever.objects.zones.{Zone, ZoneMap}
import net.psforever.packet.game.{CargoMountPointStatusMessage, ObjectDetachMessage, PlanetsideAttributeMessage}
import net.psforever.types.{PlanetSideGUID, _}
import org.specs2.mutable._
import net.psforever.services.{RemoverActor, ServiceManager}
import net.psforever.services.ServiceManager
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import scala.concurrent.duration._
@ -342,23 +342,7 @@ class VehicleControlPrepareForDeletionTest extends ActorTest {
"VehicleControl" should {
"submit for unregistering when marked for deconstruction" in {
vehicle.Actor ! Vehicle.Deconstruct()
val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds)
assert(
vehicle_msg.head match {
case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v eq vehicle) && (z == vehicle.Zone)
case _ => false
}
)
val vehicle_msg_final = vehicleProbe.receiveN(1, 6 seconds)
assert(
vehicle_msg_final.head match {
case VehicleServiceMessage("test", VehicleAction.UnloadVehicle(_, z, v, PlanetSideGUID(1))) =>
(v eq vehicle) && (z == vehicle.Zone)
case _ => false
}
)
vehicleProbe.expectNoMessage(5 seconds)
}
}
}
@ -383,7 +367,7 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest {
"kick all players when marked for deconstruction" in {
vehicle.Actor ! Vehicle.Deconstruct()
val vehicle_msg = vehicleProbe.receiveN(2, 500 milliseconds)
val vehicle_msg = vehicleProbe.receiveN(1, 500 milliseconds)
assert(
vehicle_msg.head match {
case VehicleServiceMessage(
@ -396,12 +380,6 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest {
)
assert(player1.VehicleSeated.isEmpty)
assert(vehicle.Seats(1).Occupant.isEmpty)
assert(
vehicle_msg(1) match {
case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v eq vehicle) && (z == vehicle.Zone)
case _ => false
}
)
}
}
}
@ -451,7 +429,7 @@ class VehicleControlPrepareForDeletionMountedInTest extends FreedContextActorTes
"if mounted as cargo, self-eject when marked for deconstruction" in {
vehicle.Actor ! Vehicle.Deconstruct()
val vehicle_msg = vehicleProbe.receiveN(7, 500 milliseconds)
val vehicle_msg = vehicleProbe.receiveN(6, 500 milliseconds)
//dismounting as cargo messages
assert(
vehicle_msg.head match {
@ -523,12 +501,6 @@ class VehicleControlPrepareForDeletionMountedInTest extends FreedContextActorTes
)
assert(player1.VehicleSeated.isEmpty)
assert(vehicle.Seats(1).Occupant.isEmpty)
assert(
vehicle_msg(6) match {
case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v eq vehicle) && (z == vehicle.Zone)
case _ => false
}
)
}
}
}
@ -580,7 +552,7 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor
"if with mounted cargo, eject it when marked for deconstruction" in {
lodestar.Actor ! Vehicle.Deconstruct()
val vehicle_msg = vehicleProbe.receiveN(7, 500 milliseconds)
val vehicle_msg = vehicleProbe.receiveN(6, 500 milliseconds)
assert(
vehicle_msg.head match {
case VehicleServiceMessage(
@ -650,13 +622,6 @@ class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActor
case _ => false
}
)
//cargo dismounting messages
assert(
vehicle_msg(6) match {
case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v eq lodestar) && (z == vehicle.Zone)
case _ => false
}
)
}
}
}

View file

@ -2,6 +2,7 @@
package objects
import java.util.concurrent.atomic.AtomicInteger
import akka.actor.ActorContext
import base.ActorTest
import net.psforever.objects.entity.IdentifiableEntity
@ -19,6 +20,7 @@ import org.specs2.mutable.Specification
import akka.actor.typed.scaladsl.adapter._
import net.psforever.actors.zone.ZoneActor
import net.psforever.objects.avatar.Avatar
import net.psforever.services.ServiceManager
import scala.concurrent.duration._
@ -120,6 +122,7 @@ class ZoneTest extends Specification {
}
class ZoneActorTest extends ActorTest {
ServiceManager.boot
"Zone" should {
"refuse new number pools after the Actor is started" in {
val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = {} }

View file

@ -2,17 +2,20 @@
package service
import akka.actor.Props
import base.ActorTest
import akka.testkit.TestProbe
import base.{ActorTest, FreedContextActorTest}
import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle}
import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
import net.psforever.objects.vehicles.VehicleControl
import net.psforever.objects.zones.Zone
import net.psforever.objects.zones.{Zone, ZoneMap}
import net.psforever.packet.game._
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
import net.psforever.services.{Service, ServiceManager}
import net.psforever.services.local._
import scala.concurrent.duration._
class LocalService1Test extends ActorTest {
ServiceManager.boot(system)
@ -118,15 +121,19 @@ class DeployableMapIconTest extends ActorTest {
}
}
class DoorClosesTest extends ActorTest {
ServiceManager.boot(system)
class DoorClosesTest extends FreedContextActorTest {
val probe = new TestProbe(system)
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
override def SetupNumberPools() : Unit = { }
}
zone.init(context)
expectNoMessage(500 milliseconds)
"LocalService" should {
"pass DoorCloses" in {
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
service ! Service.Join("test")
service ! LocalServiceMessage("test", LocalAction.DoorCloses(PlanetSideGUID(10), PlanetSideGUID(40)))
expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.DoorCloses(PlanetSideGUID(40))))
zone.LocalEvents.tell(Service.Join("test"), probe.ref)
zone.LocalEvents ! LocalServiceMessage("test", LocalAction.DoorCloses(PlanetSideGUID(10), PlanetSideGUID(40)))
probe.expectMsg(LocalServiceResponse("/test/Local", PlanetSideGUID(10), LocalResponse.DoorCloses(PlanetSideGUID(40))))
}
}
}

View file

@ -509,7 +509,7 @@ object RemoverActorTest {
final case class DeletionTaskRunAlert()
class TestRemover extends RemoverActor {
class TestRemover(taskResolver: ActorRef) extends RemoverActor(taskResolver) {
import net.psforever.objects.guid.{Task, TaskResolver}
val FirstStandardDuration = 1 seconds