From 4f1e4381a4b1ffea842ca8af5293bac817a303ba Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 9 May 2018 21:28:16 -0400 Subject: [PATCH] added feature to reset the vehicle terminal if it should get stuck while fulfilling an order --- .../pad/VehicleSpawnControl.scala | 47 ++++++++++++++++++- .../serverobject/pad/VehicleSpawnPad.scala | 3 +- .../src/main/scala/WorldSessionActor.scala | 25 ++++++---- 3 files changed, 64 insertions(+), 11 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 47f8f119..4229cc61 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 @@ -44,6 +44,15 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase def FactionObject : FactionAffinity = pad + import akka.actor.SupervisorStrategy._ + override val supervisorStrategy = { + import akka.actor.OneForOneStrategy + OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 10 seconds) { + case _ : akka.actor.ActorKilledException => Restart + case _ => Resume + } + } + def receive : Receive = checkBehavior.orElse { case VehicleSpawnPad.VehicleOrder(player, vehicle) => trace(s"order from $player for $vehicle received") @@ -86,6 +95,20 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase periodicReminder.cancel } + case VehicleSpawnControl.ProcessControl.Flush => + if(!periodicReminder.isCancelled) { + periodicReminder.cancel + orders.foreach { VehicleSpawnControl.CancelOrder(_, Continent) } + orders = Nil + trackedOrder match { + case Some(entry) => + VehicleSpawnControl.CancelOrder(entry, Continent) + case None => ; + } + trackedOrder = None + concealPlayer ! akka.actor.Kill //will cause the actor to restart, which will abort any trapped messages + } + case _ => ; } @@ -127,7 +150,8 @@ object VehicleSpawnControl { object ProcessControl extends Enumeration { val Reminder, - GetNewOrder + GetNewOrder, + Flush = Value } /** @@ -232,6 +256,27 @@ object VehicleSpawnControl { VehicleSpawnControl.recursiveBlockedReminder(recipients.iterator, wrecked) } + /** + * Cancel this vehicle order and inform the person who made it, if possible. + * @param entry the order being cancelled + * @param zone the continent on which the vehicle was registered + * @param context an `ActorContext` object for which to create the `TaskResolver` object + */ + def CancelOrder(entry : VehicleSpawnControl.Order, zone : Zone)(implicit context : ActorContext) : Unit = { + val vehicle = entry.vehicle + if(vehicle.Seats.values.count(_.isOccupied) == 0) { + if(vehicle.Actor != ActorRef.noSender) { + VehicleSpawnControl.DisposeSpawnedVehicle(entry, zone) + } + else { + VehicleSpawnControl.DisposeVehicle(entry, zone) + } + if(entry.sendTo != ActorRef.noSender) { + entry.sendTo ! VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Cancelled) + } + } + } + // @tailrec private final def recursiveFindOrder(iter : Iterator[VehicleSpawnControl.Order], target : ActorRef, index : Int = 0) : Option[Int] = { // if(!iter.hasNext) { // None diff --git a/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala index 7412b7cd..3daf42b0 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala @@ -163,7 +163,8 @@ object VehicleSpawnPad { object Reminders extends Enumeration { val Queue, //optional data is the numeric position in the queue - Blocked //optional data is a message regarding the blockage + Blocked, //optional data is a message regarding the blockage + Cancelled = Value } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 42477531..989ea0af 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -25,7 +25,7 @@ import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech import net.psforever.objects.serverobject.locks.IFFLock import net.psforever.objects.serverobject.mblocker.Locker -import net.psforever.objects.serverobject.pad.VehicleSpawnPad +import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} import net.psforever.objects.serverobject.pad.process.{AutoDriveControls, VehicleSpawnControlGuided} import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate} import net.psforever.objects.serverobject.terminals.{MatrixTerminalDefinition, ProximityTerminal, Terminal} @@ -435,7 +435,9 @@ class WorldSessionActor extends Actor with MDCContextAware { } case VehicleResponse.ConcealPlayer(player_guid) => - sendResponse(GenericObjectActionMessage(player_guid, 36)) + //TODO this is the correct message; but, I don't know how to undo the effects of it + //sendResponse(GenericObjectActionMessage(player_guid, 36)) + sendResponse(PlanetsideAttributeMessage(player_guid, 29, 1)) case VehicleResponse.DismountVehicle(unk1, unk2) => if(tplayer_guid != guid) { @@ -491,11 +493,8 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(GenericObjectActionMessage(pad_guid, 92)) case VehicleResponse.RevealPlayer(player_guid) => - //TODO any action will cause the player to appear after the effects of ConcealPlayer - if(player.GUID == player_guid) { - sendResponse(ChatMsg(ChatMessageType.CMT_OPEN, true, "", "You are in a strange situation.", None)) - KillPlayer(player) - } + //TODO see note in ConcealPlayer + sendResponse(PlanetsideAttributeMessage(player_guid, 29, 0)) case VehicleResponse.SeatPermissions(vehicle_guid, seat_group, permission) => if(tplayer_guid != guid) { @@ -1096,7 +1095,9 @@ class WorldSessionActor extends Actor with MDCContextAware { case VehicleSpawnPad.Reminders.Blocked => s"The vehicle spawn where you placed your order is blocked. ${data.getOrElse("")}" case VehicleSpawnPad.Reminders.Queue => - s"Your position in the vehicle spawn queue is ${data.get}." + s"Your position in the vehicle spawn queue is ${data.getOrElse("last")}." + case VehicleSpawnPad.Reminders.Cancelled => + "Your vehicle order has been cancelled." }) sendResponse(ChatMsg(ChatMessageType.CMT_OPEN, true, "", msg, None)) @@ -1704,7 +1705,13 @@ class WorldSessionActor extends Actor with MDCContextAware { } if(messagetype == ChatMessageType.CMT_DESTROY) { - self ! PacketCoding.CreateGamePacket(0, RequestDestroyMessage(PlanetSideGUID(contents.toInt))) + val guid = contents.toInt + continent.Map.TerminalToSpawnPad.get(guid) match { + case Some(padGUID) => + continent.GUID(padGUID).get.asInstanceOf[VehicleSpawnPad].Actor ! VehicleSpawnControl.ProcessControl.Flush + case None => + self ! PacketCoding.CreateGamePacket(0, RequestDestroyMessage(PlanetSideGUID(guid))) + } } if (messagetype == ChatMessageType.CMT_VOICE) {