From 73d0553b2cb2c7e0307257a70b828929fb0c9aad Mon Sep 17 00:00:00 2001 From: FateJH Date: Mon, 6 Nov 2017 18:16:23 -0500 Subject: [PATCH] added error messaging for vehicle-decon Actor, should something go wrong with the unregistering process --- .../src/main/scala/WorldSessionActor.scala | 30 +++++++++++++ .../vehicle/support/DeconstructionActor.scala | 42 ++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 45345fa2..9c40a280 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -1692,6 +1692,13 @@ class WorldSessionActor extends Actor with MDCContextAware { ) } + /** + * Construct tasking that adds a completed and registered vehicle into the scene. + * Use this function to renew the globally unique identifiers on a vehicle that has already been added to the scene once. + * @param vehicle the `Vehicle` object + * @see `RegisterNewVehicle` + * @return a `TaskResolver.GiveTask` message + */ def RegisterVehicle(vehicle : Vehicle) : TaskResolver.GiveTask = { TaskResolver.GiveTask( new Task() { @@ -1716,6 +1723,16 @@ class WorldSessionActor extends Actor with MDCContextAware { ) } + /** + * Construct tasking that adds a completed and registered vehicle into the scene. + * The major difference between `RegisterVehicle` and `RegisterNewVehicle` is the assumption that this vehicle lacks an internal `Actor`. + * Before being finished, that vehicle is supplied an `Actor` such that it may function properly. + * This function wraps around `RegisterVehicle` and is used in case, prior to this event, + * the vehicle is being brought into existence from scratch and was never a member of any `Zone`. + * @param obj the `Vehicle` object + * @see `RegisterVehicle` + * @return a `TaskResolver.GiveTask` message + */ def RegisterNewVehicle(obj : Vehicle) : TaskResolver.GiveTask = { TaskResolver.GiveTask( new Task() { @@ -1936,10 +1953,23 @@ object WorldSessionActor { def isCancelled() : Boolean = true } + /** + * Calculate the actual distance between two points. + * @param pos1 the first point + * @param pos2 the second point + * @return the distance + */ def Distance(pos1 : Vector3, pos2 : Vector3) : Float = { math.sqrt(DistanceSquared(pos1, pos2)).toFloat } + /** + * Calculate the squared distance between two points. + * Though some time is saved care must be taken that any comparative distance is also squared. + * @param pos1 the first point + * @param pos2 the second point + * @return the distance + */ def DistanceSquared(pos1 : Vector3, pos2 : Vector3) : Float = { val dx : Float = pos1.x - pos2.x val dy : Float = pos1.y - pos2.y diff --git a/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala b/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala index 441da912..4d09b927 100644 --- a/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala +++ b/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala @@ -3,7 +3,7 @@ package services.vehicle.support import akka.actor.{Actor, ActorRef, Cancellable} import net.psforever.objects.Vehicle -import net.psforever.objects.guid.GUIDTask +import net.psforever.objects.guid.TaskResolver import net.psforever.objects.vehicles.Seat import net.psforever.objects.zones.Zone import net.psforever.packet.game.PlanetSideGUID @@ -79,7 +79,7 @@ class DeconstructionActor extends Actor { entry.zone.Transport ! Zone.DespawnVehicle(vehicle) context.parent ! DeconstructionActor.DeleteVehicle(vehicle.GUID, zone.Id) //call up to the main event system context.parent ! VehicleServiceMessage.RevokeActorControl(vehicle) //call up to a sibling manager - taskResolver ! GUIDTask.UnregisterVehicle(vehicle)(zone.GUID) + taskResolver ! DeconstructionTask(vehicle, zone) }) if(vehiclesRemain.nonEmpty) { @@ -88,9 +88,39 @@ class DeconstructionActor extends Actor { scrappingProcess = context.system.scheduler.scheduleOnce(short_timeout, self, DeconstructionActor.TryDeleteVehicle()) } + case DeconstructionActor.FailureToDeleteVehicle(localVehicle, localZone, ex) => + org.log4s.getLogger.error(s"vehicle deconstruction: $localVehicle failed to be properly cleaned up from zone $localZone - $ex") + case _ => ; } + /** + * Construct a middleman `Task` intended to return error messages to the `DeconstructionActor`. + * @param vehicle the `Vehicle` object + * @param zone the `Zone` in which the vehicle resides + * @return a `TaskResolver.GiveTask` message + */ + def DeconstructionTask(vehicle : Vehicle, zone : Zone) : TaskResolver.GiveTask = { + import net.psforever.objects.guid.{GUIDTask, Task} + TaskResolver.GiveTask ( + new Task() { + private val localVehicle = vehicle + private val localZone = zone + private val localAnnounce = self + + override def isComplete : Task.Resolution.Value = Task.Resolution.Success + + def Execute(resolver : ActorRef) : Unit = { + resolver ! scala.util.Success(this) + } + + override def onFailure(ex : Throwable): Unit = { + localAnnounce ! DeconstructionActor.FailureToDeleteVehicle(localVehicle, localZone, ex) + } + }, List(GUIDTask.UnregisterVehicle(vehicle)(zone.GUID)) + ) + } + /** * Iterate over entries in a `List` until an entry that does not exceed the time limit is discovered. * Separate the original `List` into two: @@ -168,6 +198,14 @@ object DeconstructionActor { */ private final case class TryDeleteVehicle() + /** + * Error-passing message carrying information out of the final deconstruction GUID unregistering task. + * @param vehicle the `Vehicle` object + * @param zone the `Zone` in which the vehicle may or may not reside + * @param ex information regarding what happened + */ + private final case class FailureToDeleteVehicle(vehicle : Vehicle, zone : Zone, ex : Throwable) + /** * Entry of vehicle information. * The `zone` is maintained separately as a necessity, required to complete the deletion of the vehicle