Interim 2 (#477)

* changed DefaultCancellable.obj with Default.Cancellable and deleted the former (as unnecessary)

* changed ActorRef.noSender with Default.Actor for PlanetSideServerObject entities

* Actor.noSender -> ActorRef.noSender, for consistency

* player name in log messages; zoneLoaded and zoneReload flags; upstream message count

* Default object tests; expanded the set current avatar loop

* fallback cases for unsuccessful zone/avatar load process

* completing the trials of the god Travis

* forgot to reactivate kamon
This commit is contained in:
Fate-JH 2020-05-30 12:28:10 -04:00 committed by GitHub
parent 765816a4d2
commit d6397d54a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 523 additions and 302 deletions

View file

@ -0,0 +1,47 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
object Default {
//cancellable
import akka.actor.Cancellable
protected class InternalCancellable extends Cancellable {
override def cancel : Boolean = true
override def isCancelled : Boolean = true
}
private val cancellable : Cancellable = new InternalCancellable
/**
* Used to initialize the value of a re-usable `Cancellable` object.
* By convention, it always acts like it has been cancelled before and can be cancelled.
* Should be replaced with pertinent `Cancellable` logic through the initialization of an executor.
*/
final def Cancellable : Cancellable = cancellable
//actor
import akka.actor.{Actor => AkkaActor, ActorRef, ActorSystem, DeadLetter, Props}
/**
* An actor designed to wrap around `deadLetters` and redirect all normal messages to it.
* This measure is more to "protect" `deadLetters` than anything else.
* Even if it is stopped, it still fulfills exactly the same purpose!
* The original target to which the actor is assigned will not be implicitly accredited.
*/
private class DefaultActor extends AkkaActor {
def receive : Receive = {
case msg => context.system.deadLetters ! DeadLetter(msg, sender, self)
}
}
private var defaultRef : ActorRef = ActorRef.noSender
/**
* Instigate the default actor.
* @param sys the actor universe under which this default actor will exist
* @return the new default actor
*/
def apply(sys : ActorSystem) : ActorRef = {
if(defaultRef == ActorRef.noSender) {
defaultRef = sys.actorOf(Props[DefaultActor], name = s"system-default-actor")
}
defaultRef
}
final def Actor : ActorRef = defaultRef
}

View file

@ -1,18 +0,0 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
/**
* Used to initialize the value of a re-usable `Cancellable` object.
* By convention, it always acts like it has been cancelled before and can be cancelled.
* Should be replaced with pertinent `Cancellable` logic through the initialization of an executor.
*/
object DefaultCancellable {
import akka.actor.Cancellable
protected class InternalCancellable extends Cancellable {
override def cancel : Boolean = true
override def isCancelled : Boolean = true
}
final val obj : Cancellable = new InternalCancellable
}

View file

@ -20,7 +20,7 @@ class ImplantSlot {
/** whether this implant is ready for use */ /** whether this implant is ready for use */
private var initialized : Boolean = false private var initialized : Boolean = false
/** a cancellable timer that can be used to set an implant as initialized once complete */ /** a cancellable timer that can be used to set an implant as initialized once complete */
private var initializeTimer: Cancellable = DefaultCancellable.obj private var initializeTimer: Cancellable = Default.Cancellable
/** is this implant active */ /** is this implant active */
private var active : Boolean = false private var active : Boolean = false

View file

@ -125,7 +125,7 @@ class Player(private val core : Avatar) extends PlanetSideServerObject
def Stamina_=(assignStamina : Int) : Int = { def Stamina_=(assignStamina : Int) : Int = {
stamina = if(isAlive) { math.min(math.max(0, assignStamina), MaxStamina) } else { 0 } stamina = if(isAlive) { math.min(math.max(0, assignStamina), MaxStamina) } else { 0 }
if(Actor != ActorRef.noSender) { if(Actor != Default.Actor) {
Actor ! Player.StaminaChanged(Stamina) Actor ! Player.StaminaChanged(Stamina)
} }

View file

@ -1,7 +1,6 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects package net.psforever.objects
import akka.actor.ActorRef
import net.psforever.objects.definition.VehicleDefinition import net.psforever.objects.definition.VehicleDefinition
import net.psforever.objects.equipment.{Equipment, EquipmentSize, EquipmentSlot, JammableUnit} import net.psforever.objects.equipment.{Equipment, EquipmentSize, EquipmentSlot, JammableUnit}
import net.psforever.objects.inventory.{Container, GridInventory, InventoryTile} import net.psforever.objects.inventory.{Container, GridInventory, InventoryTile}
@ -546,14 +545,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends AmenityOwner
false false
} }
override def hashCode() : Int = { override def hashCode() : Int = Actor.hashCode()
Actor match {
case ActorRef.noSender =>
super.hashCode()
case actor =>
actor.hashCode()
}
}
/** /**
* Override the string representation to provide additional information. * Override the string representation to provide additional information.

View file

@ -2,7 +2,7 @@
package net.psforever.objects.avatar package net.psforever.objects.avatar
import akka.actor.Actor import akka.actor.Actor
import net.psforever.objects.{DefaultCancellable, GlobalDefinitions, ImplantSlot, Player, Players, Tool} import net.psforever.objects.{Default, GlobalDefinitions, ImplantSlot, Player, Players, Tool}
import net.psforever.objects.ballistics.{PlayerSource, ResolvedProjectile, SourceEntry} import net.psforever.objects.ballistics.{PlayerSource, ResolvedProjectile, SourceEntry}
import net.psforever.objects.definition.ImplantDefinition import net.psforever.objects.definition.ImplantDefinition
import net.psforever.objects.equipment.{Ammo, JammableBehavior, JammableUnit} import net.psforever.objects.equipment.{Ammo, JammableBehavior, JammableUnit}
@ -33,7 +33,7 @@ class PlayerControl(player : Player) extends Actor
private [this] val damageLog = org.log4s.getLogger(Damageable.LogChannel) private [this] val damageLog = org.log4s.getLogger(Damageable.LogChannel)
// A collection of timers for each slot to trigger stamina drain on an interval // A collection of timers for each slot to trigger stamina drain on an interval
val implantSlotStaminaDrainTimers = mutable.HashMap(0 -> DefaultCancellable.obj, 1 -> DefaultCancellable.obj, 2 -> DefaultCancellable.obj) val implantSlotStaminaDrainTimers = mutable.HashMap(0 -> Default.Cancellable, 1 -> Default.Cancellable, 2 -> Default.Cancellable)
def receive : Receive = jammableBehavior def receive : Receive = jammableBehavior
.orElse(takesDamage) .orElse(takesDamage)
@ -46,7 +46,7 @@ class PlayerControl(player : Player) extends Actor
if(status == 0 && (implantSlot.Active || !implantSlot.Initialized)) { if(status == 0 && (implantSlot.Active || !implantSlot.Initialized)) {
// Cancel stamina drain timer // Cancel stamina drain timer
implantSlotStaminaDrainTimers(slot).cancel() implantSlotStaminaDrainTimers(slot).cancel()
implantSlotStaminaDrainTimers(slot) = DefaultCancellable.obj implantSlotStaminaDrainTimers(slot) = Default.Cancellable
implantSlot.Active = false implantSlot.Active = false
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, player.Implant(slot).id * 2)) // Deactivation sound / effect player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, player.Implant(slot).id * 2)) // Deactivation sound / effect
@ -60,7 +60,7 @@ class PlayerControl(player : Player) extends Actor
// todo: Deactivate implants server side when actions like zoning happen. (Other actions?) // todo: Deactivate implants server side when actions like zoning happen. (Other actions?)
log.warn(s"Implant ${slot} is already active, but activating again") log.warn(s"Implant ${slot} is already active, but activating again")
implantSlotStaminaDrainTimers(slot).cancel() implantSlotStaminaDrainTimers(slot).cancel()
implantSlotStaminaDrainTimers(slot) = DefaultCancellable.obj implantSlotStaminaDrainTimers(slot) = Default.Cancellable
} }
implantSlot.Active = true implantSlot.Active = true
@ -104,9 +104,9 @@ class PlayerControl(player : Player) extends Actor
if(implantSlot.Installed.isDefined) { if(implantSlot.Installed.isDefined) {
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.SendResponse(player.GUID, AvatarImplantMessage(player.GUID, ImplantAction.Initialization, slot, 1))) player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.SendResponse(player.GUID, AvatarImplantMessage(player.GUID, ImplantAction.Initialization, slot, 1)))
implantSlot.Initialized = true implantSlot.Initialized = true
if(implantSlot.InitializeTimer != DefaultCancellable.obj) { if(implantSlot.InitializeTimer != Default.Cancellable) {
implantSlot.InitializeTimer.cancel() implantSlot.InitializeTimer.cancel()
implantSlot.InitializeTimer = DefaultCancellable.obj implantSlot.InitializeTimer = Default.Cancellable
} }
} }
@ -463,9 +463,9 @@ object PlayerControl {
val implantSlot = player.ImplantSlot(slot) val implantSlot = player.ImplantSlot(slot)
implantSlot.Initialized = false implantSlot.Initialized = false
if(implantSlot.InitializeTimer != DefaultCancellable.obj) { if(implantSlot.InitializeTimer != Default.Cancellable) {
implantSlot.InitializeTimer.cancel() implantSlot.InitializeTimer.cancel()
implantSlot.InitializeTimer = DefaultCancellable.obj implantSlot.InitializeTimer = Default.Cancellable
} }
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.Id, AvatarAction.SendResponse(player.GUID, AvatarImplantMessage(player.GUID, ImplantAction.Initialization, slot, 0))) player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.Id, AvatarAction.SendResponse(player.GUID, AvatarImplantMessage(player.GUID, ImplantAction.Initialization, slot, 0)))
} }

View file

@ -2,8 +2,8 @@
package net.psforever.objects.ce package net.psforever.objects.ce
import akka.actor.ActorContext import akka.actor.ActorContext
import net.psforever.objects.{Default, PlanetSideGameObject, TelepadDeployable, Vehicle}
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.{PlanetSideGameObject, TelepadDeployable, Vehicle}
import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.objects.vehicles.Utility import net.psforever.objects.vehicles.Utility
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
@ -50,8 +50,8 @@ object TelepadLike {
*/ */
def Setup(obj : Amenity, context : ActorContext) : Unit = { def Setup(obj : Amenity, context : ActorContext) : Unit = {
obj.asInstanceOf[TelepadLike].Router = obj.Owner.GUID obj.asInstanceOf[TelepadLike].Router = obj.Owner.GUID
import akka.actor.{ActorRef, Props} import akka.actor.Props
if(obj.Actor == ActorRef.noSender) { if(obj.Actor == Default.Actor) {
obj.Actor = context.actorOf(Props(classOf[TelepadControl], obj), PlanetSideServerObject.UniqueActorName(obj)) obj.Actor = context.actorOf(Props(classOf[TelepadControl], obj), PlanetSideServerObject.UniqueActorName(obj))
} }
} }

View file

@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.definition package net.psforever.objects.definition
import akka.actor.{ActorContext, ActorRef} import akka.actor.ActorContext
import net.psforever.objects.PlanetSideGameObject import net.psforever.objects.{Default, PlanetSideGameObject}
import net.psforever.objects.ce.{Deployable, DeployableCategory, DeployedItem} import net.psforever.objects.ce.{Deployable, DeployableCategory, DeployedItem}
import net.psforever.objects.definition.converter.SmallDeployableConverter import net.psforever.objects.definition.converter.SmallDeployableConverter
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
@ -68,6 +68,6 @@ object SimpleDeployableDefinition {
def SimpleUninitialize(obj : PlanetSideServerObject, context : ActorContext) : Unit = { def SimpleUninitialize(obj : PlanetSideServerObject, context : ActorContext) : Unit = {
context.stop(obj.Actor) context.stop(obj.Actor)
obj.Actor = ActorRef.noSender obj.Actor = Default.Actor
} }
} }

View file

@ -2,7 +2,7 @@
package net.psforever.objects.equipment package net.psforever.objects.equipment
import akka.actor.{Actor, Cancellable} import akka.actor.{Actor, Cancellable}
import net.psforever.objects.{DefaultCancellable, PlanetSideGameObject, Tool} import net.psforever.objects.{Default, PlanetSideGameObject, Tool}
import net.psforever.objects.ballistics.ResolvedProjectile import net.psforever.objects.ballistics.ResolvedProjectile
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.vehicles.MountedWeapons import net.psforever.objects.vehicles.MountedWeapons
@ -111,9 +111,9 @@ trait JammableBehavior {
/** flag for jammed sound */ /** flag for jammed sound */
protected var jammedSound : Boolean = false protected var jammedSound : Boolean = false
/** the sound timer */ /** the sound timer */
protected var jammeredSoundTimer : Cancellable = DefaultCancellable.obj protected var jammeredSoundTimer : Cancellable = Default.Cancellable
/** the effect timer */ /** the effect timer */
protected var jammeredStatusTimer : Cancellable = DefaultCancellable.obj protected var jammeredStatusTimer : Cancellable = Default.Cancellable
/** `ZoneAware` is used for callback to the event systems */ /** `ZoneAware` is used for callback to the event systems */
def JammableObject : PlanetSideServerObject with JammableUnit with ZoneAware def JammableObject : PlanetSideServerObject with JammableUnit with ZoneAware

View file

@ -5,6 +5,7 @@ import java.util.concurrent.TimeoutException
import akka.actor.{Actor, ActorRef, Cancellable} import akka.actor.{Actor, ActorRef, Cancellable}
import akka.routing.Broadcast import akka.routing.Broadcast
import net.psforever.objects.Default
import scala.annotation.tailrec import scala.annotation.tailrec
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
@ -16,7 +17,7 @@ class TaskResolver() extends Actor {
/** list of all work currently managed by this resolver */ /** list of all work currently managed by this resolver */
private val tasks : ListBuffer[TaskResolver.TaskEntry] = new ListBuffer[TaskResolver.TaskEntry] private val tasks : ListBuffer[TaskResolver.TaskEntry] = new ListBuffer[TaskResolver.TaskEntry]
/** scheduled termination of tardy managed work */ /** scheduled termination of tardy managed work */
private var timeoutCleanup : Cancellable = TaskResolver.DefaultCancellable private var timeoutCleanup : Cancellable = Default.Cancellable
/** logging utilities; default to tracing */ /** logging utilities; default to tracing */
private[this] val log = org.log4s.getLogger private[this] val log = org.log4s.getLogger
private def trace(msg : String) = log.trace(msg) private def trace(msg : String) = log.trace(msg)
@ -109,7 +110,7 @@ class TaskResolver() extends Actor {
* @param resolver the `TaskResolver` that distributed this work, thus determining that this work is a sub-task; * @param resolver the `TaskResolver` that distributed this work, thus determining that this work is a sub-task;
* by default, no one, as the work is identified as a main task * by default, no one, as the work is identified as a main task
*/ */
private def QueueSubtasks(task : Task, subtasks : List[TaskResolver.GiveTask], resolver : ActorRef = Actor.noSender) : Unit = { private def QueueSubtasks(task : Task, subtasks : List[TaskResolver.GiveTask], resolver : ActorRef = ActorRef.noSender) : Unit = {
val entry : TaskResolver.TaskEntry = TaskResolver.TaskEntry(task, subtasks.map(task => task.task), resolver) val entry : TaskResolver.TaskEntry = TaskResolver.TaskEntry(task, subtasks.map(task => task.task), resolver)
tasks += entry tasks += entry
trace(s"enqueue task $task") trace(s"enqueue task $task")
@ -347,7 +348,7 @@ object TaskResolver {
* //@param isASubtask whether this work is intermediary or the last in a dependency chain * //@param isASubtask whether this work is intermediary or the last in a dependency chain
* @param supertaskRef the `TaskResolver` that will handle work that depends on the outcome of this work * @param supertaskRef the `TaskResolver` that will handle work that depends on the outcome of this work
*/ */
private final case class TaskEntry(task : Task, subtasks : List[Task] = Nil, supertaskRef : ActorRef = Actor.noSender) { private final case class TaskEntry(task : Task, subtasks : List[Task] = Nil, supertaskRef : ActorRef = ActorRef.noSender) {
private var start : Long = 0L private var start : Long = 0L
private var isExecuting : Boolean = false private var isExecuting : Boolean = false
@ -368,14 +369,6 @@ object TaskResolver {
} }
} }
/**
* A placeholder `Cancellable` object for the time-out checking functionality.
*/
private final val DefaultCancellable = new Cancellable() {
def cancel : Boolean = true
def isCancelled() : Boolean = true
}
/** /**
* Scan across a group of tasks to determine which ones match the target completion status. * Scan across a group of tasks to determine which ones match the target completion status.
* @param iter an `Iterator` of enqueued `TaskEntry` indices * @param iter an `Iterator` of enqueued `TaskEntry` indices

View file

@ -2,41 +2,67 @@
package net.psforever.objects.serverobject package net.psforever.objects.serverobject
import akka.actor.ActorRef import akka.actor.ActorRef
import net.psforever.objects.PlanetSideGameObject import net.psforever.objects.{Default, PlanetSideGameObject}
import net.psforever.objects.entity.NoGUIDException import net.psforever.objects.entity.NoGUIDException
import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.zones.ZoneAware import net.psforever.objects.zones.ZoneAware
/** /**
* An object layered on top of the standard game object class that maintains an internal `ActorRef`. * An object layered on top of the standard game object class that maintains an internal `ActorRef`.
* A measure of synchronization can be managed using this `Actor`. * A measure of synchronization can be managed using this `Actor` as a "controlling agent."
*/ */
abstract class PlanetSideServerObject extends PlanetSideGameObject abstract class PlanetSideServerObject extends PlanetSideGameObject
with FactionAffinity with FactionAffinity
with ZoneAware { with ZoneAware {
private var actor = ActorRef.noSender private var actor : ActorRef = ActorRef.noSender
private var getActorFunc : ()=>ActorRef = PlanetSideServerObject.getDefaultActor
/** /**
* Retrieve a reference to the internal `Actor`. * Retrieve a reference to the internal `Actor`.
* @return the internal `ActorRef` * @return the internal `ActorRef`
*/ */
def Actor : ActorRef = actor def Actor : ActorRef = getActorFunc()
/** /**
* Assign an `Actor` to act for this server object. * Assign an `Actor` to act for this server object.
* This reference is only set once, that is, as long as the internal `ActorRef` directs to `Actor.noSender` (`null`). * This reference is only set once, that is, as long as the internal `ActorRef` directs to `ActorRef.noSender` (`null`).
* @param control the `Actor` whose functionality will govern this server object * @param control the `Actor` whose functionality will govern this server object
* @return the current internal `ActorRef` * @return the current internal `ActorRef`
*/ */
def Actor_=(control : ActorRef) : ActorRef = { def Actor_=(control : ActorRef) : ActorRef = {
if(actor == ActorRef.noSender || control == ActorRef.noSender) { if(control == Default.Actor) {
actor = control ResetControl()
} }
actor else {
actor = control
getActorFunc = PlanetSideServerObject.doGetLocalActor(this)
actor
}
}
def ResetControl() : ActorRef = {
getActorFunc = PlanetSideServerObject.getDefaultActor
val out = actor
actor = ActorRef.noSender
out
} }
} }
object PlanetSideServerObject { object PlanetSideServerObject {
/**
* Before the internal control agency of a respective server object is ever set,
* a default control agency will be produced.
* @return the value pointed to by `Default.Actor`
*/
private def getDefaultActor() : ActorRef = { Default.Actor }
/**
* Allow retrieving a reference to the internal `Actor`.
* @see o the server object
* @return the internal `ActorRef`
*/
private def doGetLocalActor(o : PlanetSideServerObject)() : ActorRef = o.actor
/** /**
* `Actor` entities require unique names over the course of the lifetime of the `ActorSystem` object. * `Actor` entities require unique names over the course of the lifetime of the `ActorSystem` object.
* To produce this name, a composition of three strings separated by underscores is assembled.<br> * To produce this name, a composition of three strings separated by underscores is assembled.<br>

View file

@ -5,7 +5,7 @@ import akka.actor.{ActorContext, Cancellable, Props}
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
import net.psforever.objects.serverobject.pad.process.{VehicleSpawnControlBase, VehicleSpawnControlConcealPlayer} import net.psforever.objects.serverobject.pad.process.{VehicleSpawnControlBase, VehicleSpawnControlConcealPlayer}
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
import net.psforever.objects.{DefaultCancellable, Player, Vehicle} import net.psforever.objects.{Default, Player, Vehicle}
import services.RemoverActor import services.RemoverActor
import services.vehicle.VehicleServiceMessage import services.vehicle.VehicleServiceMessage
@ -32,7 +32,7 @@ import scala.concurrent.duration._
*/ */
class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase(pad) with FactionAffinityBehavior.Check { class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase(pad) with FactionAffinityBehavior.Check {
/** a reminder sent to future customers */ /** a reminder sent to future customers */
var periodicReminder : Cancellable = DefaultCancellable.obj var periodicReminder : Cancellable = Default.Cancellable
/** a list of vehicle orders that have been submitted for this spawn pad */ /** a list of vehicle orders that have been submitted for this spawn pad */
var orders : List[VehicleSpawnControl.Order] = List.empty[VehicleSpawnControl.Order] var orders : List[VehicleSpawnControl.Order] = List.empty[VehicleSpawnControl.Order]
/** the current vehicle order being acted upon; /** the current vehicle order being acted upon;

View file

@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.pad.process package net.psforever.objects.serverobject.pad.process
import akka.actor.{ActorRef, Props} import akka.actor.Props
import net.psforever.objects.Vehicle import net.psforever.objects.{Default, Vehicle}
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.ExecutionContext.Implicits.global
@ -29,7 +29,7 @@ class VehicleSpawnControlSeatDriver(pad : VehicleSpawnPad) extends VehicleSpawnC
def receive : Receive = { def receive : Receive = {
case order @ VehicleSpawnControl.Order(_, vehicle) => case order @ VehicleSpawnControl.Order(_, vehicle) =>
if(vehicle.Actor == ActorRef.noSender) { //wait for a necessary vehicle component to be loaded if(vehicle.Actor == Default.Actor) { //wait for a necessary vehicle component to be loaded
context.system.scheduler.scheduleOnce(50 milliseconds, self, order) context.system.scheduler.scheduleOnce(50 milliseconds, self, order)
} }
else { else {

View file

@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.painbox
import akka.actor.{Actor, Cancellable} import akka.actor.{Actor, Cancellable}
import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.doors.Door
import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.{DefaultCancellable, GlobalDefinitions} import net.psforever.objects.{Default, GlobalDefinitions}
import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.types.{PlanetSideEmpire, Vector3}
import services.avatar.{AvatarAction, AvatarServiceMessage} import services.avatar.{AvatarAction, AvatarServiceMessage}
@ -12,7 +12,7 @@ import scala.concurrent.duration._
class PainboxControl(painbox: Painbox) extends Actor { class PainboxControl(painbox: Painbox) extends Actor {
private[this] val log = org.log4s.getLogger(s"Painbox") private[this] val log = org.log4s.getLogger(s"Painbox")
var painboxTick: Cancellable = DefaultCancellable.obj var painboxTick: Cancellable = Default.Cancellable
var nearestDoor: Option[Door] = None var nearestDoor: Option[Door] = None
var bBoxMinCorner = Vector3.Zero var bBoxMinCorner = Vector3.Zero
var bBoxMaxCorner = Vector3.Zero var bBoxMaxCorner = Vector3.Zero
@ -97,7 +97,7 @@ class PainboxControl(painbox: Painbox) extends Actor {
case Painbox.Stop() => case Painbox.Stop() =>
context.become(Stopped) context.become(Stopped)
painboxTick.cancel painboxTick.cancel
painboxTick = DefaultCancellable.obj painboxTick = Default.Cancellable
case Painbox.Tick() => case Painbox.Tick() =>
//todo: Account for overlapping pain fields //todo: Account for overlapping pain fields

View file

@ -3,8 +3,8 @@ package net.psforever.objects.serverobject.structures
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import akka.actor.{ActorContext, ActorRef} import akka.actor.ActorContext
import net.psforever.objects.{GlobalDefinitions, Player} import net.psforever.objects.{Default, GlobalDefinitions, Player}
import net.psforever.objects.definition.ObjectDefinition import net.psforever.objects.definition.ObjectDefinition
import net.psforever.objects.serverobject.generator.Generator import net.psforever.objects.serverobject.generator.Generator
import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.hackable.Hackable
@ -118,7 +118,7 @@ class Building(private val name: String,
} }
def TriggerZoneMapUpdate(): Unit = { def TriggerZoneMapUpdate(): Unit = {
if(Actor != ActorRef.noSender) Actor ! Building.TriggerZoneMapUpdate(Zone.Number) if(Actor != Default.Actor) Actor ! Building.TriggerZoneMapUpdate(Zone.Number)
} }
def UpdateForceDomeStatus() : Unit = { def UpdateForceDomeStatus() : Unit = {
@ -141,7 +141,7 @@ class Building(private val name: String,
} }
if(originalStatus != ForceDomeActive) { if(originalStatus != ForceDomeActive) {
if(Actor != ActorRef.noSender) { if(Actor != Default.Actor) {
Zone.LocalEvents ! LocalServiceMessage(Zone.Id, LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, GUID, ForceDomeActive)) Zone.LocalEvents ! LocalServiceMessage(Zone.Id, LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, GUID, ForceDomeActive))
Actor ! Building.SendMapUpdate(all_clients = true) Actor ! Building.SendMapUpdate(all_clients = true)
} }

View file

@ -13,8 +13,8 @@ import services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage, Gala
class BuildingControl(building : Building) extends Actor with FactionAffinityBehavior.Check { class BuildingControl(building : Building) extends Actor with FactionAffinityBehavior.Check {
def FactionObject : FactionAffinity = building def FactionObject : FactionAffinity = building
var galaxyService : ActorRef = Actor.noSender var galaxyService : ActorRef = ActorRef.noSender
var interstellarCluster : ActorRef = Actor.noSender var interstellarCluster : ActorRef = ActorRef.noSender
private[this] val log = org.log4s.getLogger private[this] val log = org.log4s.getLogger
override def preStart = { override def preStart = {

View file

@ -2,7 +2,7 @@
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import akka.actor.ActorContext import akka.actor.ActorContext
import net.psforever.objects.Player import net.psforever.objects.{Default, Player}
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.serverobject.structures.Amenity
@ -28,8 +28,8 @@ object MatrixTerminalDefinition {
* @param context hook to the local `Actor` system * @param context hook to the local `Actor` system
*/ */
def Setup(obj : Amenity, context : ActorContext) : Unit = { def Setup(obj : Amenity, context : ActorContext) : Unit = {
import akka.actor.{ActorRef, Props} import akka.actor.Props
if(obj.Actor == ActorRef.noSender) { if(obj.Actor == Default.Actor) {
obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj)) obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj))
} }
} }

View file

@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.terminals
import akka.actor.ActorContext import akka.actor.ActorContext
import net.psforever.objects.definition.ImplantDefinition import net.psforever.objects.definition.ImplantDefinition
import net.psforever.objects.{Player, Vehicle} import net.psforever.objects.{Default, Player, Vehicle}
import net.psforever.objects.equipment.Equipment import net.psforever.objects.equipment.Equipment
import net.psforever.objects.loadouts.{InfantryLoadout, VehicleLoadout} import net.psforever.objects.loadouts.{InfantryLoadout, VehicleLoadout}
import net.psforever.objects.inventory.InventoryItem import net.psforever.objects.inventory.InventoryItem
@ -340,8 +340,8 @@ object OrderTerminalDefinition {
* @param context hook to the local `Actor` system * @param context hook to the local `Actor` system
*/ */
def Setup(obj : Amenity, context : ActorContext) : Unit = { def Setup(obj : Amenity, context : ActorContext) : Unit = {
import akka.actor.{ActorRef, Props} import akka.actor.Props
if(obj.Actor == ActorRef.noSender) { if(obj.Actor == Default.Actor) {
obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj)) obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj))
} }
} }

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals package net.psforever.objects.serverobject.terminals
import net.psforever.objects.Player import net.psforever.objects.{Default, Player}
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
import net.psforever.objects.serverobject.structures.Amenity import net.psforever.objects.serverobject.structures.Amenity
import net.psforever.types.Vector3 import net.psforever.types.Vector3
@ -74,8 +74,8 @@ object ProximityTerminal {
* @param context hook to the local `Actor` system * @param context hook to the local `Actor` system
*/ */
def Setup(obj : Amenity, context : ActorContext) : Unit = { def Setup(obj : Amenity, context : ActorContext) : Unit = {
import akka.actor.{ActorRef, Props} import akka.actor.Props
if(obj.Actor == ActorRef.noSender) { if(obj.Actor == Default.Actor) {
obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj)) obj.Actor = context.actorOf(Props(classOf[ProximityTerminalControl], obj), PlanetSideServerObject.UniqueActorName(obj))
obj.Actor ! Service.Startup() obj.Actor ! Service.Startup()
} }

View file

@ -30,7 +30,7 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
def DamageableObject = term def DamageableObject = term
def RepairableObject = term def RepairableObject = term
var terminalAction : Cancellable = DefaultCancellable.obj var terminalAction : Cancellable = Default.Cancellable
val callbacks : mutable.ListBuffer[ActorRef] = new mutable.ListBuffer[ActorRef]() val callbacks : mutable.ListBuffer[ActorRef] = new mutable.ListBuffer[ActorRef]()
val log = org.log4s.getLogger val log = org.log4s.getLogger

View file

@ -2,7 +2,7 @@
package net.psforever.objects.serverobject.tube package net.psforever.objects.serverobject.tube
import akka.actor.ActorContext import akka.actor.ActorContext
import net.psforever.objects.SpawnPointDefinition import net.psforever.objects.{Default, SpawnPointDefinition}
import net.psforever.objects.definition.converter.SpawnTubeConverter import net.psforever.objects.definition.converter.SpawnTubeConverter
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.structures.{Amenity, AmenityDefinition} import net.psforever.objects.serverobject.structures.{Amenity, AmenityDefinition}
@ -23,8 +23,8 @@ object SpawnTubeDefinition {
* @param context hook to the local `Actor` system * @param context hook to the local `Actor` system
*/ */
def Setup(obj : Amenity, context : ActorContext) : Unit = { def Setup(obj : Amenity, context : ActorContext) : Unit = {
import akka.actor.{ActorRef, Props} import akka.actor.Props
if(obj.Actor == ActorRef.noSender) { if(obj.Actor == Default.Actor) {
obj.Actor = context.actorOf(Props(classOf[SpawnTubeControl], obj), PlanetSideServerObject.UniqueActorName(obj)) obj.Actor = context.actorOf(Props(classOf[SpawnTubeControl], obj), PlanetSideServerObject.UniqueActorName(obj))
} }
} }

View file

@ -3,7 +3,7 @@ package net.psforever.objects.serverobject.turret
import akka.actor.Actor import akka.actor.Actor
import net.psforever.objects.ballistics.ResolvedProjectile import net.psforever.objects.ballistics.ResolvedProjectile
import net.psforever.objects.{DefaultCancellable, GlobalDefinitions, Player, Tool} import net.psforever.objects.{Default, GlobalDefinitions, Player, Tool}
import net.psforever.objects.equipment.{Ammo, JammableMountedWeapons} import net.psforever.objects.equipment.{Ammo, JammableMountedWeapons}
import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.serverobject.mount.MountableBehavior import net.psforever.objects.serverobject.mount.MountableBehavior
@ -41,7 +41,7 @@ class FacilityTurretControl(turret : FacilityTurret) extends Actor
def RepairableObject = turret def RepairableObject = turret
// Used for timing ammo recharge for vanu turrets in caves // Used for timing ammo recharge for vanu turrets in caves
var weaponAmmoRechargeTimer = DefaultCancellable.obj var weaponAmmoRechargeTimer = Default.Cancellable
def receive : Receive = checkBehavior def receive : Receive = checkBehavior
.orElse(jammableBehavior) .orElse(jammableBehavior)
@ -65,7 +65,7 @@ class FacilityTurretControl(turret : FacilityTurret) extends Actor
} }
case FacilityTurret.WeaponDischarged() => case FacilityTurret.WeaponDischarged() =>
if(weaponAmmoRechargeTimer != DefaultCancellable.obj) { if(weaponAmmoRechargeTimer != Default.Cancellable) {
weaponAmmoRechargeTimer.cancel() weaponAmmoRechargeTimer.cancel()
} }
@ -83,9 +83,9 @@ class FacilityTurretControl(turret : FacilityTurret) extends Actor
} }
} }
if(weapon.Magazine == weapon.MaxMagazine && weaponAmmoRechargeTimer != DefaultCancellable.obj) { if(weapon.Magazine == weapon.MaxMagazine && weaponAmmoRechargeTimer != Default.Cancellable) {
weaponAmmoRechargeTimer.cancel() weaponAmmoRechargeTimer.cancel()
weaponAmmoRechargeTimer = DefaultCancellable.obj weaponAmmoRechargeTimer = Default.Cancellable
} }
case _ => ; case _ => ;

View file

@ -1,7 +1,7 @@
// Copyright (c) 2019 PSForever // Copyright (c) 2019 PSForever
package net.psforever.objects.teamwork package net.psforever.objects.teamwork
import akka.actor.{Actor, ActorContext, ActorRef, Props} import akka.actor.{ActorContext, ActorRef, Props}
import net.psforever.types.SquadWaypoints import net.psforever.types.SquadWaypoints
import services.teamwork.SquadService.WaypointData import services.teamwork.SquadService.WaypointData
import services.teamwork.SquadSwitchboard import services.teamwork.SquadSwitchboard
@ -74,7 +74,7 @@ class SquadFeatures(val Squad : Squad) {
def Stop : SquadFeatures = { def Stop : SquadFeatures = {
switchboard ! akka.actor.PoisonPill switchboard ! akka.actor.PoisonPill
switchboard = Actor.noSender switchboard = ActorRef.noSender
waypoints = Array.empty waypoints = Array.empty
this this
} }

View file

@ -15,8 +15,8 @@ import scala.concurrent.duration._
trait CargoBehavior { trait CargoBehavior {
_ : Actor => _ : Actor =>
private var cargoMountTimer : Cancellable = DefaultCancellable.obj private var cargoMountTimer : Cancellable = Default.Cancellable
private var cargoDismountTimer : Cancellable = DefaultCancellable.obj private var cargoDismountTimer : Cancellable = Default.Cancellable
/* gate-keep mounting behavior so that unit does not try to dismount as cargo, or mount different vehicle */ /* gate-keep mounting behavior so that unit does not try to dismount as cargo, or mount different vehicle */
private var isMounting : Option[PlanetSideGUID] = None private var isMounting : Option[PlanetSideGUID] = None

View file

@ -269,6 +269,6 @@ object InternalTelepadDefinition {
def SimpleUninitialize(obj : PlanetSideServerObject, context : ActorContext) : Unit = { def SimpleUninitialize(obj : PlanetSideServerObject, context : ActorContext) : Unit = {
context.stop(obj.Actor) context.stop(obj.Actor)
obj.Actor = ActorRef.noSender obj.Actor = Default.Actor
} }
} }

View file

@ -52,7 +52,7 @@ class VehicleControl(vehicle : Vehicle) extends Actor
/** cheap flag for whether the vehicle is decaying */ /** cheap flag for whether the vehicle is decaying */
var decaying : Boolean = false var decaying : Boolean = false
/** primary vehicle decay timer */ /** primary vehicle decay timer */
var decayTimer : Cancellable = DefaultCancellable.obj var decayTimer : Cancellable = Default.Cancellable
def receive : Receive = Enabled def receive : Receive = Enabled
@ -62,7 +62,7 @@ class VehicleControl(vehicle : Vehicle) extends Actor
decayTimer.cancel decayTimer.cancel
vehicle.Utilities.values.foreach { util => vehicle.Utilities.values.foreach { util =>
context.stop(util().Actor) context.stop(util().Actor)
util().Actor = ActorRef.noSender util().Actor = Default.Actor
} }
} }

View file

@ -1,7 +1,7 @@
package net.psforever.objects.zones package net.psforever.objects.zones
import akka.actor.{Actor, Cancellable} import akka.actor.{Actor, Cancellable}
import net.psforever.objects.{DefaultCancellable, Player} import net.psforever.objects.{Default, Player}
import net.psforever.objects.definition.ObjectDefinition import net.psforever.objects.definition.ObjectDefinition
import net.psforever.objects.serverobject.structures.{Building, SphereOfInfluence} import net.psforever.objects.serverobject.structures.{Building, SphereOfInfluence}
import net.psforever.types.Vector3 import net.psforever.types.Vector3
@ -12,7 +12,7 @@ import scala.concurrent.duration._
class SphereOfInfluenceActor(zone: Zone) extends Actor { class SphereOfInfluenceActor(zone: Zone) extends Actor {
var sois : Iterable[(Building, Int)] = Nil var sois : Iterable[(Building, Int)] = Nil
var populateTick : Cancellable = DefaultCancellable.obj var populateTick : Cancellable = Default.Cancellable
//private[this] val log = org.log4s.getLogger(s"${zone.Id.capitalize}-SphereOfInfluenceActor") //private[this] val log = org.log4s.getLogger(s"${zone.Id.capitalize}-SphereOfInfluenceActor")
def receive : Receive = Stopped def receive : Receive = Stopped

View file

@ -55,13 +55,13 @@ import scala.util.Try
*/ */
class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
/** Governs general synchronized external requests. */ /** Governs general synchronized external requests. */
private var actor = ActorRef.noSender private var actor = Default.Actor
/** Actor that handles SOI related functionality, for example if a player is in a SOI **/ /** Actor that handles SOI related functionality, for example if a player is in a SOI **/
private var soi = ActorRef.noSender private var soi = Default.Actor
/** Used by the globally unique identifier system to coordinate requests. */ /** Used by the globally unique identifier system to coordinate requests. */
private var accessor : ActorRef = ActorRef.noSender private var accessor : ActorRef = Default.Actor
/** The basic support structure for the globally unique number system used by this `Zone`. */ /** The basic support structure for the globally unique number system used by this `Zone`. */
private var guid : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(65536)) private var guid : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(65536))
/** A synchronized `List` of items (`Equipment`) dropped by players on the ground and can be collected again. */ /** A synchronized `List` of items (`Equipment`) dropped by players on the ground and can be collected again. */
@ -69,19 +69,19 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
/** */ /** */
private val vehicles : ListBuffer[Vehicle] = ListBuffer[Vehicle]() private val vehicles : ListBuffer[Vehicle] = ListBuffer[Vehicle]()
/** Used by the `Zone` to coordinate `Equipment` dropping and collection requests. */ /** Used by the `Zone` to coordinate `Equipment` dropping and collection requests. */
private var ground : ActorRef = ActorRef.noSender private var ground : ActorRef = Default.Actor
/** */ /** */
private val constructions : ListBuffer[PlanetSideGameObject with Deployable] = ListBuffer[PlanetSideGameObject with Deployable]() private val constructions : ListBuffer[PlanetSideGameObject with Deployable] = ListBuffer[PlanetSideGameObject with Deployable]()
/** */ /** */
private var deployables : ActorRef = ActorRef.noSender private var deployables : ActorRef = Default.Actor
/** */ /** */
private var transport : ActorRef = ActorRef.noSender private var transport : ActorRef = Default.Actor
/** */ /** */
private val players : TrieMap[Avatar, Option[Player]] = TrieMap[Avatar, Option[Player]]() private val players : TrieMap[Avatar, Option[Player]] = TrieMap[Avatar, Option[Player]]()
/** */ /** */
private val corpses : ListBuffer[Player] = ListBuffer[Player]() private val corpses : ListBuffer[Player] = ListBuffer[Player]()
/** */ /** */
private var population : ActorRef = ActorRef.noSender private var population : ActorRef = Default.Actor
private var buildings : PairMap[Int, Building] = PairMap.empty[Int, Building] private var buildings : PairMap[Int, Building] = PairMap.empty[Int, Building]
@ -92,7 +92,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
/** key - spawn zone id, value - buildings belonging to spawn zone */ /** key - spawn zone id, value - buildings belonging to spawn zone */
private var spawnGroups : Map[Building, List[SpawnPoint]] = PairMap[Building, List[SpawnPoint]]() private var spawnGroups : Map[Building, List[SpawnPoint]] = PairMap[Building, List[SpawnPoint]]()
/** */ /** */
private var projector : ActorRef = ActorRef.noSender private var projector : ActorRef = Default.Actor
/** */ /** */
private var hotspots : ListBuffer[HotSpotInfo] = ListBuffer[HotSpotInfo]() private var hotspots : ListBuffer[HotSpotInfo] = ListBuffer[HotSpotInfo]()
/** */ /** */
@ -102,11 +102,11 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
/** calculate a duration from a given interaction's participants */ /** calculate a duration from a given interaction's participants */
private var hotspotTimeFunc : (SourceEntry, SourceEntry)=>FiniteDuration = Zone.HotSpot.Rules.NoTime private var hotspotTimeFunc : (SourceEntry, SourceEntry)=>FiniteDuration = Zone.HotSpot.Rules.NoTime
/** */ /** */
private var avatarEvents : ActorRef = ActorRef.noSender private var avatarEvents : ActorRef = Default.Actor
/** */ /** */
private var localEvents : ActorRef = ActorRef.noSender private var localEvents : ActorRef = Default.Actor
/** */ /** */
private var vehicleEvents : ActorRef = ActorRef.noSender private var vehicleEvents : ActorRef = Default.Actor
/** /**
* Establish the basic accessible conditions necessary for a functional `Zone`.<br> * Establish the basic accessible conditions necessary for a functional `Zone`.<br>
@ -126,7 +126,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
* @param context a reference to an `ActorContext` necessary for `Props` * @param context a reference to an `ActorContext` necessary for `Props`
*/ */
def Init(implicit context : ActorContext) : Unit = { def Init(implicit context : ActorContext) : Unit = {
if(accessor == ActorRef.noSender) { if(accessor == Default.Actor) {
SetupNumberPools() SetupNumberPools()
accessor = context.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], this.guid, UniqueNumberSystem.AllocateNumberPoolActors(this.guid))), s"$Id-uns") accessor = context.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], this.guid, UniqueNumberSystem.AllocateNumberPoolActors(this.guid))), s"$Id-uns")
ground = context.actorOf(Props(classOf[ZoneGroundActor], this, equipmentOnGround), s"$Id-ground") ground = context.actorOf(Props(classOf[ZoneGroundActor], this, equipmentOnGround), s"$Id-ground")
@ -187,7 +187,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
* @see `ZoneActor` * @see `ZoneActor`
*/ */
def Actor_=(zoneActor : ActorRef) : ActorRef = { def Actor_=(zoneActor : ActorRef) : ActorRef = {
if(actor == ActorRef.noSender) { if(actor == Default.Actor) {
actor = zoneActor actor = zoneActor
} }
Actor Actor
@ -226,7 +226,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
* @return synchronized reference to the globally unique identifier system * @return synchronized reference to the globally unique identifier system
*/ */
def GUID(hub : NumberPoolHub) : Boolean = { def GUID(hub : NumberPoolHub) : Boolean = {
if(actor == ActorRef.noSender && guid.Pools.values.foldLeft(0)(_ + _.Count) == 0) { if(actor == Default.Actor && guid.Pools.values.foldLeft(0)(_ + _.Count) == 0) {
import org.fusesource.jansi.Ansi.Color.RED import org.fusesource.jansi.Ansi.Color.RED
import org.fusesource.jansi.Ansi.ansi import org.fusesource.jansi.Ansi.ansi
println(ansi().fgBright(RED).a(s"""Caution: replacement of the number pool system for zone $Id; function is for testing purposes only""").reset()) println(ansi().fgBright(RED).a(s"""Caution: replacement of the number pool system for zone $Id; function is for testing purposes only""").reset())
@ -248,7 +248,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
* `false`, if the new pool can not be created because the system has already been started * `false`, if the new pool can not be created because the system has already been started
*/ */
def AddPool(name : String, pool : Seq[Int]) : Boolean = { def AddPool(name : String, pool : Seq[Int]) : Boolean = {
if(accessor == ActorRef.noSender) { if(accessor == Default.Actor) {
guid.AddPool(name, pool.toList) guid.AddPool(name, pool.toList)
true true
} }
@ -266,7 +266,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
* `false`, if the new pool can not be removed because the system has already been started * `false`, if the new pool can not be removed because the system has already been started
*/ */
def RemovePool(name : String) : Boolean = { def RemovePool(name : String) : Boolean = {
if(accessor == ActorRef.noSender) { if(accessor == Default.Actor) {
guid.RemovePool(name) guid.RemovePool(name)
true true
} }

View file

@ -2,7 +2,7 @@
package net.psforever.objects.zones package net.psforever.objects.zones
import akka.actor.{Actor, ActorRef, Cancellable, Props} import akka.actor.{Actor, ActorRef, Cancellable, Props}
import net.psforever.objects.DefaultCancellable import net.psforever.objects.Default
import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.types.{PlanetSideEmpire, Vector3}
import services.ServiceManager import services.ServiceManager
@ -59,7 +59,7 @@ class ZoneHotSpotProjector(zone : Zone, hotspots : ListBuffer[HotSpotInfo], blan
/** a hook for the `GalaxyService` used to broadcast messages */ /** a hook for the `GalaxyService` used to broadcast messages */
var galaxy : ActorRef = ActorRef.noSender var galaxy : ActorRef = ActorRef.noSender
/** the timer for the blanking process */ /** the timer for the blanking process */
var blanking : Cancellable = DefaultCancellable.obj var blanking : Cancellable = Default.Cancellable
/** how long to wait in between blanking periods while hotspots decay */ /** how long to wait in between blanking periods while hotspots decay */
var blankingDelay : FiniteDuration = blankingTime var blankingDelay : FiniteDuration = blankingTime

View file

@ -3,7 +3,7 @@ package net.psforever.objects.zones
import akka.actor.{Actor, ActorRef, Props} import akka.actor.{Actor, ActorRef, Props}
import net.psforever.objects.avatar.PlayerControl import net.psforever.objects.avatar.PlayerControl
import net.psforever.objects.{Avatar, Player} import net.psforever.objects.{Avatar, Default, Player}
import scala.annotation.tailrec import scala.annotation.tailrec
import scala.collection.concurrent.TrieMap import scala.collection.concurrent.TrieMap
@ -47,7 +47,7 @@ class ZonePopulationActor(zone : Zone, playerMap : TrieMap[Avatar, Option[Player
sender ! Zone.Population.PlayerAlreadySpawned(zone, player) sender ! Zone.Population.PlayerAlreadySpawned(zone, player)
} }
else if(newToZone) { else if(newToZone) {
player.Actor = context.actorOf(Props(classOf[PlayerControl], player), s"${player.CharId}_${player.GUID.guid}_${System.currentTimeMillis}") player.Actor = context.actorOf(Props(classOf[PlayerControl], player), name = GetPlayerControlName(player, None))
player.Zone = zone player.Zone = zone
} }
case None => case None =>
@ -63,10 +63,15 @@ class ZonePopulationActor(zone : Zone, playerMap : TrieMap[Avatar, Option[Player
} }
case Zone.Corpse.Add(player) => case Zone.Corpse.Add(player) =>
CorpseAdd(player, corpseList) if(CorpseAdd(player, corpseList)) {
player.Actor = context.actorOf(Props(classOf[PlayerControl], player), name = s"corpse_of_${GetPlayerControlName(player, None)}")
player.Zone = zone
}
case Zone.Corpse.Remove(player) => case Zone.Corpse.Remove(player) =>
CorpseRemove(player, corpseList) if(CorpseRemove(player, corpseList)) {
PlayerLeave(player)
}
case _ => ; case _ => ;
} }
@ -168,17 +173,19 @@ object ZonePopulationActor {
* @param player a `Player` object * @param player a `Player` object
* @param corpseList a list of `Player` objects * @param corpseList a list of `Player` objects
*/ */
def CorpseRemove(player : Player, corpseList : ListBuffer[Player]) : Unit = { def CorpseRemove(player : Player, corpseList : ListBuffer[Player]) : Boolean = {
recursiveFindCorpse(corpseList.iterator, player) match { recursiveFindCorpse(corpseList.iterator, player) match {
case None => ; case None =>
false
case Some(index) => case Some(index) =>
corpseList.remove(index) corpseList.remove(index)
true
} }
} }
def PlayerLeave(player : Player) : Unit = { def PlayerLeave(player : Player) : Unit = {
player.Actor ! akka.actor.PoisonPill player.Actor ! akka.actor.PoisonPill
player.Actor = ActorRef.noSender player.Actor = Default.Actor
} }
/** /**
@ -202,4 +209,14 @@ object ZonePopulationActor {
} }
} }
} }
def GetPlayerControlName(player : Player, old : Option[ActorRef]) : String = {
old match {
case Some(control) =>
val nameNumber = control.toString.split("/").last //split on '/'
nameNumber.split("#").head //split on '#'
case None => ;
s"${player.CharId}_${player.GUID.guid}_${System.currentTimeMillis}" //new
}
}
} }

View file

@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package net.psforever.objects.zones package net.psforever.objects.zones
import akka.actor.{Actor, ActorRef, Props} import akka.actor.{Actor, Props}
import net.psforever.objects.Vehicle import net.psforever.objects.{Default, Vehicle}
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.vehicles.VehicleControl import net.psforever.objects.vehicles.VehicleControl
@ -38,7 +38,7 @@ class ZoneVehicleActor(zone : Zone, vehicleList : ListBuffer[Vehicle]) extends A
else if(vehicleList.contains(vehicle)) { else if(vehicleList.contains(vehicle)) {
sender ! Zone.Vehicle.CanNotSpawn(zone, vehicle, "already in zone") sender ! Zone.Vehicle.CanNotSpawn(zone, vehicle, "already in zone")
} }
else if(vehicle.Actor != ActorRef.noSender) { else if(vehicle.Actor != Default.Actor) {
sender ! Zone.Vehicle.CanNotSpawn(zone, vehicle, "already in another zone") sender ! Zone.Vehicle.CanNotSpawn(zone, vehicle, "already in another zone")
} }
else { else {
@ -52,7 +52,7 @@ class ZoneVehicleActor(zone : Zone, vehicleList : ListBuffer[Vehicle]) extends A
case Some(index) => case Some(index) =>
vehicleList.remove(index) vehicleList.remove(index)
context.stop(vehicle.Actor) context.stop(vehicle.Actor)
vehicle.Actor = ActorRef.noSender vehicle.Actor = Default.Actor
case None => ; case None => ;
sender ! Zone.Vehicle.CanNotDespawn(zone, vehicle, "can not find") sender ! Zone.Vehicle.CanNotDespawn(zone, vehicle, "can not find")
} }

View file

@ -1,10 +1,10 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package services package services
import akka.actor.{Actor, ActorRef, Cancellable} import akka.actor.{ActorRef, Cancellable}
import net.psforever.objects.guid.TaskResolver import net.psforever.objects.guid.TaskResolver
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
import net.psforever.objects.{DefaultCancellable, PlanetSideGameObject} import net.psforever.objects.{Default, PlanetSideGameObject}
import net.psforever.types.Vector3 import net.psforever.types.Vector3
import services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions} import services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
@ -33,7 +33,7 @@ abstract class RemoverActor extends SupportActor[RemoverActor.Entry] {
/** /**
* The timer that checks whether entries in the first pool are still eligible for that pool. * The timer that checks whether entries in the first pool are still eligible for that pool.
*/ */
var firstTask : Cancellable = DefaultCancellable.obj var firstTask : Cancellable = Default.Cancellable
/** /**
* The first pool of objects waiting to be processed for removal. * The first pool of objects waiting to be processed for removal.
*/ */
@ -42,13 +42,13 @@ abstract class RemoverActor extends SupportActor[RemoverActor.Entry] {
/** /**
* The timer that checks whether entries in the second pool are still eligible for that pool. * The timer that checks whether entries in the second pool are still eligible for that pool.
*/ */
var secondTask : Cancellable = DefaultCancellable.obj var secondTask : Cancellable = Default.Cancellable
/** /**
* The second pool of objects waiting to be processed for removal. * The second pool of objects waiting to be processed for removal.
*/ */
var secondHeap : List[RemoverActor.Entry] = List() var secondHeap : List[RemoverActor.Entry] = List()
protected var taskResolver : ActorRef = Actor.noSender protected var taskResolver : ActorRef = ActorRef.noSender
val sameEntryComparator = new SimilarityComparator[RemoverActor.Entry]() { val sameEntryComparator = new SimilarityComparator[RemoverActor.Entry]() {
def Test(entry1 : RemoverActor.Entry, entry2 : RemoverActor.Entry) : Boolean = { def Test(entry1 : RemoverActor.Entry, entry2 : RemoverActor.Entry) : Boolean = {

View file

@ -1,12 +1,12 @@
// Copyright (c) 2017 PSForever
package services package services
// Copyright (c) 2017 PSForever
import akka.actor.{Actor, ActorIdentity, ActorRef, ActorSystem, Identify, Props} import akka.actor.{Actor, ActorIdentity, ActorRef, ActorSystem, Identify, Props}
import scala.collection.mutable import scala.collection.mutable
object ServiceManager { object ServiceManager {
var serviceManager = Actor.noSender var serviceManager = ActorRef.noSender
def boot(implicit system : ActorSystem) = { def boot(implicit system : ActorSystem) = {
serviceManager = system.actorOf(Props[ServiceManager], "service") serviceManager = system.actorOf(Props[ServiceManager], "service")

View file

@ -190,7 +190,7 @@ class PersistenceMonitor(name : String, squadService : ActorRef, taskResolver :
/** the last-reported game coordinate position of this player */ /** the last-reported game coordinate position of this player */
var lastPosition : Vector3 = Vector3.Zero var lastPosition : Vector3 = Vector3.Zero
/** the ongoing amount of permissible inactivity */ /** the ongoing amount of permissible inactivity */
var timer : Cancellable = DefaultCancellable.obj var timer : Cancellable = Default.Cancellable
/** the sparingly-used log */ /** the sparingly-used log */
val log = org.log4s.getLogger val log = org.log4s.getLogger
@ -309,7 +309,7 @@ class PersistenceMonitor(name : String, squadService : ActorRef, taskResolver :
player.Position = Vector3.Zero player.Position = Vector3.Zero
player.Health = 0 player.Health = 0
inZone.GUID(player.VehicleOwned) match { inZone.GUID(player.VehicleOwned) match {
case Some(vehicle : Vehicle) if vehicle.OwnerName.contains(player.Name) && vehicle.Actor != ActorRef.noSender => case Some(vehicle : Vehicle) if vehicle.OwnerName.contains(player.Name) && vehicle.Actor != Default.Actor =>
vehicle.Actor ! Vehicle.Ownership(None) vehicle.Actor ! Vehicle.Ownership(None)
case _ => ; case _ => ;
} }

View file

@ -2,7 +2,7 @@
package services.local.support package services.local.support
import akka.actor.{Actor, Cancellable} import akka.actor.{Actor, Cancellable}
import net.psforever.objects.{DefaultCancellable, Player} import net.psforever.objects.{Default, Player}
import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.doors.Door
import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
@ -18,7 +18,7 @@ import scala.concurrent.duration._
*/ */
class DoorCloseActor() extends Actor { class DoorCloseActor() extends Actor {
/** The periodic `Executor` that checks for doors to be closed */ /** The periodic `Executor` that checks for doors to be closed */
private var doorCloserTrigger : Cancellable = DefaultCancellable.obj private var doorCloserTrigger : Cancellable = Default.Cancellable
/** A `List` of currently open doors */ /** A `List` of currently open doors */
private var openDoors : List[DoorCloseActor.DoorEntry] = Nil private var openDoors : List[DoorCloseActor.DoorEntry] = Nil
//private[this] val log = org.log4s.getLogger //private[this] val log = org.log4s.getLogger

View file

@ -1,7 +1,7 @@
package services.local.support package services.local.support
import akka.actor.{Actor, Cancellable} import akka.actor.{Actor, Cancellable}
import net.psforever.objects.DefaultCancellable import net.psforever.objects.Default
import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.serverobject.terminals.CaptureTerminal import net.psforever.objects.serverobject.terminals.CaptureTerminal
@ -14,7 +14,7 @@ import scala.concurrent.duration.{FiniteDuration, _}
class HackCaptureActor extends Actor { class HackCaptureActor extends Actor {
private [this] val log = org.log4s.getLogger private [this] val log = org.log4s.getLogger
private var clearTrigger : Cancellable = DefaultCancellable.obj private var clearTrigger : Cancellable = Default.Cancellable
/** A `List` of currently hacked server objects */ /** A `List` of currently hacked server objects */
private var hackedObjects : List[HackCaptureActor.HackEntry] = Nil private var hackedObjects : List[HackCaptureActor.HackEntry] = Nil

View file

@ -4,7 +4,7 @@ package services.local.support
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import akka.actor.{Actor, Cancellable} import akka.actor.{Actor, Cancellable}
import net.psforever.objects.DefaultCancellable import net.psforever.objects.Default
import net.psforever.objects.serverobject.hackable.Hackable import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
@ -20,7 +20,7 @@ import scala.concurrent.duration._
*/ */
class HackClearActor() extends Actor { class HackClearActor() extends Actor {
/** The periodic `Executor` that checks for server objects to be unhacked */ /** The periodic `Executor` that checks for server objects to be unhacked */
private var clearTrigger : Cancellable = DefaultCancellable.obj private var clearTrigger : Cancellable = Default.Cancellable
/** A `List` of currently hacked server objects */ /** A `List` of currently hacked server objects */
private var hackedObjects : List[HackClearActor.HackEntry] = Nil private var hackedObjects : List[HackClearActor.HackEntry] = Nil
private[this] val log = org.log4s.getLogger private[this] val log = org.log4s.getLogger

View file

@ -9,7 +9,7 @@ import services.support.{SimilarityComparator, SupportActor}
import scala.concurrent.duration._ import scala.concurrent.duration._
class RouterTelepadActivation extends SupportActor[RouterTelepadActivation.Entry] { class RouterTelepadActivation extends SupportActor[RouterTelepadActivation.Entry] {
var activationTask : Cancellable = DefaultCancellable.obj var activationTask : Cancellable = Default.Cancellable
var telepadList : List[RouterTelepadActivation.Entry] = List() var telepadList : List[RouterTelepadActivation.Entry] = List()
val sameEntryComparator = new SimilarityComparator[RouterTelepadActivation.Entry]() { val sameEntryComparator = new SimilarityComparator[RouterTelepadActivation.Entry]() {
def Test(entry1 : RouterTelepadActivation.Entry, entry2 : RouterTelepadActivation.Entry) : Boolean = { def Test(entry1 : RouterTelepadActivation.Entry, entry2 : RouterTelepadActivation.Entry) : Boolean = {

View file

@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package services.vehicle.support package services.vehicle.support
import akka.actor.{Actor, ActorRef, Cancellable} import akka.actor.{ActorRef, Cancellable}
import net.psforever.objects.{AmmoBox, DefaultCancellable, PlanetSideGameObject, Tool} import net.psforever.objects.{AmmoBox, Default, PlanetSideGameObject, Tool}
import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver} import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver}
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, WeaponTurret} import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade, WeaponTurret}
@ -16,11 +16,11 @@ import services.{Service, ServiceManager}
import scala.concurrent.duration._ import scala.concurrent.duration._
class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] { class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
var task : Cancellable = DefaultCancellable.obj var task : Cancellable = Default.Cancellable
var list : List[TurretUpgrader.Entry] = List() var list : List[TurretUpgrader.Entry] = List()
private var taskResolver : ActorRef = Actor.noSender private var taskResolver : ActorRef = ActorRef.noSender
val sameEntryComparator = new SimilarityComparator[TurretUpgrader.Entry]() { val sameEntryComparator = new SimilarityComparator[TurretUpgrader.Entry]() {
def Test(entry1 : TurretUpgrader.Entry, entry2 : TurretUpgrader.Entry) : Boolean = { def Test(entry1 : TurretUpgrader.Entry, entry2 : TurretUpgrader.Entry) : Boolean = {

View file

@ -7,7 +7,7 @@ import net.psforever.objects.guid.GUIDTask.UnregisterVehicle
import services.{RemoverActor, ServiceManager} import services.{RemoverActor, ServiceManager}
class VehicleRemover extends Actor { class VehicleRemover extends Actor {
var taskResolver : ActorRef = Actor.noSender var taskResolver : ActorRef = ActorRef.noSender
override def preStart() : Unit = { override def preStart() : Unit = {
super.preStart() super.preStart()

View file

@ -1,9 +1,9 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{ActorRef, Props} import akka.actor.Props
import base.ActorTest import base.ActorTest
import net.psforever.objects.GlobalDefinitions import net.psforever.objects.{Default, GlobalDefinitions}
import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.affinity.FactionAffinity
import net.psforever.objects.serverobject.doors.{Door, DoorControl} import net.psforever.objects.serverobject.doors.{Door, DoorControl}
import net.psforever.objects.serverobject.structures._ import net.psforever.objects.serverobject.structures._
@ -72,7 +72,7 @@ class BuildingTest extends Specification {
"construct" in { "construct" in {
val bldg = Building("Building", 0, 10, Zone.Nowhere, StructureType.Building) val bldg = Building("Building", 0, 10, Zone.Nowhere, StructureType.Building)
bldg.MapId mustEqual 10 bldg.MapId mustEqual 10
bldg.Actor mustEqual ActorRef.noSender bldg.Actor mustEqual Default.Actor
bldg.Amenities mustEqual Nil bldg.Amenities mustEqual Nil
bldg.Zone mustEqual Zone.Nowhere bldg.Zone mustEqual Zone.Nowhere
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
@ -107,7 +107,7 @@ class WarpGateTest extends Specification {
"construct" in { "construct" in {
val bldg = WarpGate("WarpGate", 0, 10, Zone.Nowhere, GlobalDefinitions.warpgate) val bldg = WarpGate("WarpGate", 0, 10, Zone.Nowhere, GlobalDefinitions.warpgate)
bldg.MapId mustEqual 10 bldg.MapId mustEqual 10
bldg.Actor mustEqual ActorRef.noSender bldg.Actor mustEqual Default.Actor
bldg.Amenities mustEqual Nil bldg.Amenities mustEqual Nil
bldg.Zone mustEqual Zone.Nowhere bldg.Zone mustEqual Zone.Nowhere
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
@ -120,7 +120,7 @@ class BuildingControl1Test extends ActorTest {
"construct" in { "construct" in {
val bldg = Building("Building", 0, 10, Zone.Nowhere, StructureType.Building) val bldg = Building("Building", 0, 10, Zone.Nowhere, StructureType.Building)
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test") bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test")
assert(bldg.Actor != ActorRef.noSender) assert(bldg.Actor != Default.Actor)
} }
} }
} }

View file

@ -0,0 +1,49 @@
// Copyright (c) 2020 PSForever
package objects
import akka.actor.DeadLetter
import akka.testkit.TestProbe
import base.ActorTest
import net.psforever.objects.Default
import org.specs2.mutable.Specification
import scala.concurrent.duration._
class DefaultTest extends Specification {
"Default.Cancellable" should {
"always act like it can be cancelled successfully" in {
Default.Cancellable.cancel mustEqual true
}
"always act like it was cancelled successfully" in {
Default.Cancellable.isCancelled mustEqual true
}
}
}
class DefaultActorStartedTest extends ActorTest {
"Default.Actor" should {
"send messages to deadLetters" in {
//after being started
Default(system)
val probe = new TestProbe(system)
system.eventStream.subscribe(probe.ref, classOf[DeadLetter])
Default.Actor ! "hello world"
val msg1 = probe.receiveOne(250 milliseconds)
assert(msg1.isInstanceOf[DeadLetter])
assert(msg1.asInstanceOf[DeadLetter].message equals "hello world")
//if it was stopped
system.stop(Default.Actor)
Default.Actor ! "hello world"
val msg2 = probe.receiveOne(250 milliseconds)
assert(msg2.isInstanceOf[DeadLetter])
assert(msg2.asInstanceOf[DeadLetter].message equals "hello world")
}
}
}
object DefaultActorTest {
//due to being a singleton, the original original value of the Default.Actor is cached here
val Original = Default.Actor
}

View file

@ -592,11 +592,11 @@ class TurretControlInitializeTest extends ActorTest {
"initialize" in { "initialize" in {
val obj = new TurretDeployable(GlobalDefinitions.spitfire_turret) val obj = new TurretDeployable(GlobalDefinitions.spitfire_turret)
obj.GUID = PlanetSideGUID(1) obj.GUID = PlanetSideGUID(1)
assert(obj.Actor == ActorRef.noSender) assert(obj.Actor == Default.Actor)
val init = system.actorOf(Props(classOf[DeployableTest.TurretInitializer], obj), "init_turret_test") val init = system.actorOf(Props(classOf[DeployableTest.TurretInitializer], obj), "init_turret_test")
init ! "initialize" init ! "initialize"
expectNoMessage(200 milliseconds) expectNoMessage(200 milliseconds)
assert(obj.Actor != ActorRef.noSender) assert(obj.Actor != Default.Actor)
} }
} }
} }
@ -609,11 +609,11 @@ class TurretControlUninitializeTest extends ActorTest {
obj.GUID = PlanetSideGUID(1) obj.GUID = PlanetSideGUID(1)
init ! "initialize" init ! "initialize"
expectNoMessage(200 milliseconds) expectNoMessage(200 milliseconds)
assert(obj.Actor != ActorRef.noSender) assert(obj.Actor != Default.Actor)
init ! "uninitialize" init ! "uninitialize"
expectNoMessage(200 milliseconds) expectNoMessage(200 milliseconds)
assert(obj.Actor == ActorRef.noSender) assert(obj.Actor == Default.Actor)
} }
} }
} }

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{Actor, ActorSystem, Props} import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import base.ActorTest import base.ActorTest
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.{GlobalDefinitions, Vehicle} import net.psforever.objects.{GlobalDefinitions, Vehicle}
@ -46,7 +46,7 @@ class DeploymentBehavior1Test extends ActorTest {
"Deployment" should { "Deployment" should {
"construct" in { "construct" in {
val obj = DeploymentTest.SetUpAgent val obj = DeploymentTest.SetUpAgent
assert(obj.Actor != Actor.noSender) assert(obj.Actor != ActorRef.noSender)
assert(obj.DeploymentState == DriveState.Mobile) assert(obj.DeploymentState == DriveState.Mobile)
} }
} }

View file

@ -1,9 +1,9 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{ActorRef, ActorSystem, Props} import akka.actor.{ActorSystem, Props}
import base.ActorTest import base.ActorTest
import net.psforever.objects.{Avatar, GlobalDefinitions, Player} import net.psforever.objects.{Avatar, Default, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.doors.{Door, DoorControl} import net.psforever.objects.serverobject.doors.{Door, DoorControl}
import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
@ -59,7 +59,7 @@ class DoorControl1Test extends ActorTest {
"construct" in { "construct" in {
val door = Door(GlobalDefinitions.door) val door = Door(GlobalDefinitions.door)
door.Actor = system.actorOf(Props(classOf[DoorControl], door), "door") door.Actor = system.actorOf(Props(classOf[DoorControl], door), "door")
assert(door.Actor != ActorRef.noSender) assert(door.Actor != Default.Actor)
} }
} }
} }

View file

@ -1,10 +1,10 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{ActorRef, Props} import akka.actor.Props
import akka.testkit.TestProbe import akka.testkit.TestProbe
import base.ActorTest import base.ActorTest
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Tool} import net.psforever.objects.{Avatar, Default, GlobalDefinitions, Player, Tool}
import net.psforever.objects.definition.ToolDefinition import net.psforever.objects.definition.ToolDefinition
import net.psforever.objects.guid.NumberPoolHub import net.psforever.objects.guid.NumberPoolHub
import net.psforever.objects.guid.source.LimitedNumberSource import net.psforever.objects.guid.source.LimitedNumberSource
@ -94,7 +94,7 @@ class FacilityTurretControl1Test extends ActorTest {
"construct" in { "construct" in {
val obj = FacilityTurret(GlobalDefinitions.manned_turret) val obj = FacilityTurret(GlobalDefinitions.manned_turret)
obj.Actor = system.actorOf(Props(classOf[FacilityTurretControl], obj), "turret-control") obj.Actor = system.actorOf(Props(classOf[FacilityTurretControl], obj), "turret-control")
assert(obj.Actor != ActorRef.noSender) assert(obj.Actor != Default.Actor)
} }
} }
} }

View file

@ -1,10 +1,10 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{ActorRef, ActorSystem, Props} import akka.actor.{ActorSystem, Props}
import base.ActorTest import base.ActorTest
import net.psforever.objects.{Avatar, Default, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.locks.{IFFLock, IFFLockControl} import net.psforever.objects.serverobject.locks.{IFFLock, IFFLockControl}
import net.psforever.objects.serverobject.structures.{Building, StructureType} import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
@ -48,7 +48,7 @@ class IFFLockControl1Test extends ActorTest {
"construct" in { "construct" in {
val lock = IFFLock(GlobalDefinitions.lock_external) val lock = IFFLock(GlobalDefinitions.lock_external)
lock.Actor = system.actorOf(Props(classOf[IFFLockControl], lock), "lock-control") lock.Actor = system.actorOf(Props(classOf[IFFLockControl], lock), "lock-control")
assert(lock.Actor != ActorRef.noSender) assert(lock.Actor != Default.Actor)
} }
} }
} }

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{ActorRef, Props} import akka.actor.Props
import base.ActorTest import base.ActorTest
import net.psforever.objects.GlobalDefinitions import net.psforever.objects.GlobalDefinitions
import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.affinity.FactionAffinity
@ -19,8 +19,8 @@ class LockerTest extends Specification {
"Locker" should { "Locker" should {
"construct" in { "construct" in {
val locker = new Locker() new Locker()
locker.Actor mustEqual ActorRef.noSender ok
} }
} }
} }

View file

@ -187,7 +187,7 @@ class PlayerControlRepairTest extends ActorTest {
assert(originalArmor < player2.MaxArmor) assert(originalArmor < player2.MaxArmor)
player2.Actor ! CommonMessages.Use(player1, Some(tool)) player2.Actor ! CommonMessages.Use(player1, Some(tool))
val msg_avatar = avatarProbe.receiveN(5, 500 milliseconds) val msg_avatar = avatarProbe.receiveN(5, 1000 milliseconds)
assert( assert(
msg_avatar.head match { msg_avatar.head match {
case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true case AvatarServiceMessage("TestCharacter1", AvatarAction.SendResponse(_, InventoryStateMessage(PlanetSideGUID(4), _, PlanetSideGUID(3), _))) => true

View file

@ -1,9 +1,9 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.{ActorRef, Props} import akka.actor.Props
import base.ActorTest import base.ActorTest
import net.psforever.objects.GlobalDefinitions import net.psforever.objects.{Default, GlobalDefinitions}
import net.psforever.objects.serverobject.tube.{SpawnTube, SpawnTubeControl, SpawnTubeDefinition} import net.psforever.objects.serverobject.tube.{SpawnTube, SpawnTubeControl, SpawnTubeDefinition}
import org.specs2.mutable.Specification import org.specs2.mutable.Specification
@ -18,7 +18,7 @@ class SpawnTubeTest extends Specification {
"SpawnTube" should { "SpawnTube" should {
"construct" in { "construct" in {
val obj = SpawnTube(GlobalDefinitions.ams_respawn_tube) val obj = SpawnTube(GlobalDefinitions.ams_respawn_tube)
obj.Actor mustEqual ActorRef.noSender obj.Actor mustEqual Default.Actor
obj.Definition mustEqual GlobalDefinitions.ams_respawn_tube obj.Definition mustEqual GlobalDefinitions.ams_respawn_tube
} }
} }
@ -29,7 +29,7 @@ class SpawnTubeControlTest extends ActorTest {
"construct" in { "construct" in {
val obj = SpawnTube(GlobalDefinitions.ams_respawn_tube) val obj = SpawnTube(GlobalDefinitions.ams_respawn_tube)
obj.Actor = system.actorOf(Props(classOf[SpawnTubeControl], obj), "spawn-tube") obj.Actor = system.actorOf(Props(classOf[SpawnTubeControl], obj), "spawn-tube")
assert(obj.Actor != ActorRef.noSender) assert(obj.Actor != Default.Actor)
} }
} }
} }

View file

@ -20,7 +20,7 @@ class UtilityTest extends Specification {
obj.UtilType mustEqual UtilityType.order_terminala obj.UtilType mustEqual UtilityType.order_terminala
obj().isInstanceOf[Terminal] mustEqual true obj().isInstanceOf[Terminal] mustEqual true
obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 613 obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 613
obj().asInstanceOf[Terminal].Actor mustEqual ActorRef.noSender obj().asInstanceOf[Terminal].Actor mustEqual Default.Actor
} }
"create an order_terminalb object" in { "create an order_terminalb object" in {
@ -28,7 +28,7 @@ class UtilityTest extends Specification {
obj.UtilType mustEqual UtilityType.order_terminalb obj.UtilType mustEqual UtilityType.order_terminalb
obj().isInstanceOf[Terminal] mustEqual true obj().isInstanceOf[Terminal] mustEqual true
obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 614 obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 614
obj().asInstanceOf[Terminal].Actor mustEqual ActorRef.noSender obj().asInstanceOf[Terminal].Actor mustEqual Default.Actor
} }
"create a matrix_terminalc object" in { "create a matrix_terminalc object" in {
@ -36,7 +36,7 @@ class UtilityTest extends Specification {
obj.UtilType mustEqual UtilityType.matrix_terminalc obj.UtilType mustEqual UtilityType.matrix_terminalc
obj().isInstanceOf[Terminal] mustEqual true obj().isInstanceOf[Terminal] mustEqual true
obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 519 obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 519
obj().asInstanceOf[Terminal].Actor mustEqual ActorRef.noSender obj().asInstanceOf[Terminal].Actor mustEqual Default.Actor
} }
"create an ams_respawn_tube object" in { "create an ams_respawn_tube object" in {
@ -44,7 +44,7 @@ class UtilityTest extends Specification {
obj.UtilType mustEqual UtilityType.ams_respawn_tube obj.UtilType mustEqual UtilityType.ams_respawn_tube
obj().isInstanceOf[SpawnTube] mustEqual true obj().isInstanceOf[SpawnTube] mustEqual true
obj().asInstanceOf[SpawnTube].Definition.ObjectId mustEqual 49 obj().asInstanceOf[SpawnTube].Definition.ObjectId mustEqual 49
obj().asInstanceOf[SpawnTube].Actor mustEqual ActorRef.noSender obj().asInstanceOf[SpawnTube].Actor mustEqual Default.Actor
} }
"create a teleportpad_terminal object" in { "create a teleportpad_terminal object" in {
@ -52,7 +52,7 @@ class UtilityTest extends Specification {
obj.UtilType mustEqual UtilityType.teleportpad_terminal obj.UtilType mustEqual UtilityType.teleportpad_terminal
obj().isInstanceOf[Terminal] mustEqual true obj().isInstanceOf[Terminal] mustEqual true
obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 853 obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 853
obj().asInstanceOf[Terminal].Actor mustEqual ActorRef.noSender obj().asInstanceOf[Terminal].Actor mustEqual Default.Actor
} }
"produce a telepad object through the teleportpad_terminal" in { "produce a telepad object through the teleportpad_terminal" in {
@ -78,7 +78,7 @@ class UtilityTest extends Specification {
obj.UtilType mustEqual UtilityType.internal_router_telepad_deployable obj.UtilType mustEqual UtilityType.internal_router_telepad_deployable
obj().isInstanceOf[Utility.InternalTelepad] mustEqual true obj().isInstanceOf[Utility.InternalTelepad] mustEqual true
obj().asInstanceOf[Utility.InternalTelepad].Definition.ObjectId mustEqual 744 obj().asInstanceOf[Utility.InternalTelepad].Definition.ObjectId mustEqual 744
obj().asInstanceOf[Utility.InternalTelepad].Actor mustEqual ActorRef.noSender obj().asInstanceOf[Utility.InternalTelepad].Actor mustEqual Default.Actor
} }
"internal_router_telepad_deployable can keep track of an object's GUID (presumedly, it's a Telepad)" in { "internal_router_telepad_deployable can keep track of an object's GUID (presumedly, it's a Telepad)" in {
@ -139,11 +139,11 @@ class UtilityTerminalATest extends ActorTest {
"wire an order_terminala Actor" in { "wire an order_terminala Actor" in {
val obj = Utility(UtilityType.order_terminala, UtilityTest.vehicle) val obj = Utility(UtilityType.order_terminala, UtilityTest.vehicle)
obj().GUID = PlanetSideGUID(1) obj().GUID = PlanetSideGUID(1)
assert(obj().Actor == ActorRef.noSender) assert(obj().Actor == Default.Actor)
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
receiveOne(Duration.create(500, "ms")) //consume and discard receiveOne(Duration.create(500, "ms")) //consume and discard
assert(obj().Actor != ActorRef.noSender) assert(obj().Actor != Default.Actor)
} }
} }
} }
@ -153,11 +153,11 @@ class UtilityTerminalBTest extends ActorTest {
"wire an order_terminalb Actor" in { "wire an order_terminalb Actor" in {
val obj = Utility(UtilityType.order_terminalb, UtilityTest.vehicle) val obj = Utility(UtilityType.order_terminalb, UtilityTest.vehicle)
obj().GUID = PlanetSideGUID(1) obj().GUID = PlanetSideGUID(1)
assert(obj().Actor == ActorRef.noSender) assert(obj().Actor == Default.Actor)
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
receiveOne(Duration.create(500, "ms")) //consume and discard receiveOne(Duration.create(500, "ms")) //consume and discard
assert(obj().Actor != ActorRef.noSender) assert(obj().Actor != Default.Actor)
} }
} }
} }
@ -167,11 +167,11 @@ class UtilityTerminalCTest extends ActorTest {
"wire a matrix_terminalc Actor" in { "wire a matrix_terminalc Actor" in {
val obj = Utility(UtilityType.matrix_terminalc, UtilityTest.vehicle) val obj = Utility(UtilityType.matrix_terminalc, UtilityTest.vehicle)
obj().GUID = PlanetSideGUID(1) obj().GUID = PlanetSideGUID(1)
assert(obj().Actor == ActorRef.noSender) assert(obj().Actor == Default.Actor)
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
receiveOne(Duration.create(500, "ms")) //consume and discard receiveOne(Duration.create(500, "ms")) //consume and discard
assert(obj().Actor != ActorRef.noSender) assert(obj().Actor != Default.Actor)
} }
} }
} }
@ -181,11 +181,11 @@ class UtilityRespawnTubeTest extends ActorTest {
"wire an ams_respawn_tube Actor" in { "wire an ams_respawn_tube Actor" in {
val obj = Utility(UtilityType.ams_respawn_tube, UtilityTest.vehicle) val obj = Utility(UtilityType.ams_respawn_tube, UtilityTest.vehicle)
obj().GUID = PlanetSideGUID(1) obj().GUID = PlanetSideGUID(1)
assert(obj().Actor == ActorRef.noSender) assert(obj().Actor == Default.Actor)
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
receiveOne(Duration.create(500, "ms")) //consume and discard receiveOne(Duration.create(500, "ms")) //consume and discard
assert(obj().Actor != ActorRef.noSender) assert(obj().Actor != Default.Actor)
} }
} }
} }
@ -195,11 +195,11 @@ class UtilityTelepadTerminalTest extends ActorTest {
"wire a teleportpad_terminal Actor" in { "wire a teleportpad_terminal Actor" in {
val obj = Utility(UtilityType.teleportpad_terminal, UtilityTest.vehicle) val obj = Utility(UtilityType.teleportpad_terminal, UtilityTest.vehicle)
obj().GUID = PlanetSideGUID(1) obj().GUID = PlanetSideGUID(1)
assert(obj().Actor == ActorRef.noSender) assert(obj().Actor == Default.Actor)
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
receiveOne(Duration.create(500, "ms")) //consume and discard receiveOne(Duration.create(500, "ms")) //consume and discard
assert(obj().Actor != ActorRef.noSender) assert(obj().Actor != Default.Actor)
} }
} }
} }
@ -211,12 +211,12 @@ class UtilityInternalTelepadTest extends ActorTest {
veh.GUID = PlanetSideGUID(101) veh.GUID = PlanetSideGUID(101)
val obj = Utility(UtilityType.internal_router_telepad_deployable, veh) val obj = Utility(UtilityType.internal_router_telepad_deployable, veh)
obj().GUID = PlanetSideGUID(1) obj().GUID = PlanetSideGUID(1)
assert(obj().Actor == ActorRef.noSender) assert(obj().Actor == Default.Actor)
assert(obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID)) assert(obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID))
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! "" system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
receiveOne(Duration.create(500, "ms")) //consume and discard receiveOne(Duration.create(500, "ms")) //consume and discard
assert(obj().Actor != ActorRef.noSender) assert(obj().Actor != Default.Actor)
assert(obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID)) assert(obj().asInstanceOf[Utility.InternalTelepad].Router.contains(veh.GUID))
} }
} }

View file

@ -1,9 +1,8 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects package objects
import akka.actor.ActorRef import net.psforever.objects.{Default, GlobalDefinitions}
import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.objects.serverobject.pad.VehicleSpawnPad
import net.psforever.objects.GlobalDefinitions
import org.specs2.mutable.Specification import org.specs2.mutable.Specification
class VehicleSpawnPadTest extends Specification { class VehicleSpawnPadTest extends Specification {
@ -16,7 +15,7 @@ class VehicleSpawnPadTest extends Specification {
"VehicleSpawnPad" should { "VehicleSpawnPad" should {
"construct" in { "construct" in {
val obj = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation) val obj = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
obj.Actor mustEqual ActorRef.noSender obj.Actor mustEqual Default.Actor
obj.Definition mustEqual GlobalDefinitions.mb_pad_creation obj.Definition mustEqual GlobalDefinitions.mb_pad_creation
} }
} }

View file

@ -92,10 +92,6 @@ class ZoneTest extends Specification {
"Zone" should { "Zone" should {
"construct" in { "construct" in {
val zone = new Zone("home3", map13, 13) val zone = new Zone("home3", map13, 13)
zone.GUID mustEqual ActorRef.noSender
zone.Ground mustEqual ActorRef.noSender
zone.Transport mustEqual ActorRef.noSender
//zone also has a unique identifier system but it can't be accessed without its the Actor GUID being initialized
zone.EquipmentOnGround mustEqual List.empty[Equipment] zone.EquipmentOnGround mustEqual List.empty[Equipment]
zone.Vehicles mustEqual List.empty[Vehicle] zone.Vehicles mustEqual List.empty[Vehicle]
zone.Players mustEqual List.empty[Player] zone.Players mustEqual List.empty[Player]

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects.number package objects.number
import akka.actor.Actor import akka.actor.ActorRef
import net.psforever.objects.guid.actor.Register import net.psforever.objects.guid.actor.Register
import org.specs2.mutable.Specification import org.specs2.mutable.Specification
@ -18,11 +18,11 @@ class RegisterTest extends Specification {
} }
"construct (object, callback)" in { "construct (object, callback)" in {
val reg = Register(obj, Actor.noSender) val reg = Register(obj, ActorRef.noSender)
reg.obj mustEqual obj reg.obj mustEqual obj
reg.number.isEmpty mustEqual true reg.number.isEmpty mustEqual true
reg.name.isEmpty mustEqual true reg.name.isEmpty mustEqual true
reg.callback.contains(Actor.noSender) mustEqual true reg.callback.contains(ActorRef.noSender) mustEqual true
} }
"construct (object, suggested number)" in { "construct (object, suggested number)" in {
@ -34,11 +34,11 @@ class RegisterTest extends Specification {
} }
"construct (object, suggested number, callback)" in { "construct (object, suggested number, callback)" in {
val reg = Register(obj, 5, Actor.noSender) val reg = Register(obj, 5, ActorRef.noSender)
reg.obj mustEqual obj reg.obj mustEqual obj
reg.number.contains(5) mustEqual true reg.number.contains(5) mustEqual true
reg.name.isEmpty mustEqual true reg.name.isEmpty mustEqual true
reg.callback.contains(Actor.noSender) mustEqual true reg.callback.contains(ActorRef.noSender) mustEqual true
} }
"construct (object, pool name)" in { "construct (object, pool name)" in {
@ -50,11 +50,11 @@ class RegisterTest extends Specification {
} }
"construct (object, pool name, callback)" in { "construct (object, pool name, callback)" in {
val reg = Register(obj, "pool", Actor.noSender) val reg = Register(obj, "pool", ActorRef.noSender)
reg.obj mustEqual obj reg.obj mustEqual obj
reg.number.isEmpty mustEqual true reg.number.isEmpty mustEqual true
reg.name.contains("pool") mustEqual true reg.name.contains("pool") mustEqual true
reg.callback.contains(Actor.noSender) mustEqual true reg.callback.contains(ActorRef.noSender) mustEqual true
} }
} }
} }

View file

@ -1,8 +1,9 @@
// Copyright (c) 2017 PSForever // Copyright (c) 2017 PSForever
package objects.terminal package objects.terminal
import akka.actor.{ActorRef, ActorSystem, Props} import akka.actor.{ActorSystem, Props}
import base.ActorTest import base.ActorTest
import net.psforever.objects.{Avatar, Default, GlobalDefinitions, Player}
import net.psforever.objects.definition.SeatDefinition import net.psforever.objects.definition.SeatDefinition
import net.psforever.objects.guid.NumberPoolHub import net.psforever.objects.guid.NumberPoolHub
import net.psforever.objects.guid.source.LimitedNumberSource import net.psforever.objects.guid.source.LimitedNumberSource
@ -12,7 +13,6 @@ import net.psforever.objects.serverobject.structures.{Building, StructureType}
import net.psforever.objects.serverobject.terminals.Terminal import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.vehicles.Seat import net.psforever.objects.vehicles.Seat
import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.objects.zones.{Zone, ZoneMap}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3} import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, Vector3}
import org.specs2.mutable.Specification import org.specs2.mutable.Specification
@ -35,7 +35,7 @@ class ImplantTerminalMechTest extends Specification {
"Implant_Terminal_Mech" should { "Implant_Terminal_Mech" should {
"construct" in { "construct" in {
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech) val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
obj.Actor mustEqual ActorRef.noSender obj.Actor mustEqual Default.Actor
obj.Definition mustEqual GlobalDefinitions.implant_terminal_mech obj.Definition mustEqual GlobalDefinitions.implant_terminal_mech
obj.Seats.keySet mustEqual Set(0) obj.Seats.keySet mustEqual Set(0)
obj.Seats(0).isInstanceOf[Seat] mustEqual true obj.Seats(0).isInstanceOf[Seat] mustEqual true
@ -65,7 +65,7 @@ class ImplantTerminalMechControl1Test extends ActorTest {
"construct" in { "construct" in {
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech) val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
obj.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], obj), "mech") obj.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], obj), "mech")
assert(obj.Actor != ActorRef.noSender) assert(obj.Actor != Default.Actor)
} }
} }
} }

View file

@ -6,6 +6,7 @@ import base.ActorTest
import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle} import net.psforever.objects.{GlobalDefinitions, SensorDeployable, Vehicle}
import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal} 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
import net.psforever.packet.game._ import net.psforever.packet.game._
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
@ -206,6 +207,7 @@ class ToggleTeleportSystemTest extends ActorTest {
"LocalService" should { "LocalService" should {
"pass ToggleTeleportSystem" in { "pass ToggleTeleportSystem" in {
val router = Vehicle(GlobalDefinitions.router) val router = Vehicle(GlobalDefinitions.router)
router.Actor = system.actorOf(Props(classOf[VehicleControl], router), "test-router")
val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service") val service = system.actorOf(Props(classOf[LocalService], Zone.Nowhere), "l_service")
service ! Service.Join("test") service ! Service.Join("test")
service ! LocalServiceMessage("test", LocalAction.ToggleTeleportSystem(PlanetSideGUID(10), router, None)) service ! LocalServiceMessage("test", LocalAction.ToggleTeleportSystem(PlanetSideGUID(10), router, None))

View file

@ -4,6 +4,7 @@ package service
import akka.actor.Props import akka.actor.Props
import base.ActorTest import base.ActorTest
import net.psforever.objects._ import net.psforever.objects._
import net.psforever.objects.vehicles.VehicleControl
import net.psforever.objects.zones.Zone import net.psforever.objects.zones.Zone
import net.psforever.types.{PlanetSideGUID, _} import net.psforever.types.{PlanetSideGUID, _}
import services.{Service, ServiceManager} import services.{Service, ServiceManager}
@ -171,6 +172,7 @@ class KickPassengerTest extends ActorTest {
class LoadVehicleTest extends ActorTest { class LoadVehicleTest extends ActorTest {
ServiceManager.boot(system) ServiceManager.boot(system)
val vehicle = Vehicle(GlobalDefinitions.quadstealth) val vehicle = Vehicle(GlobalDefinitions.quadstealth)
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "test-vehicle")
val cdata = vehicle.Definition.Packet.ConstructorData(vehicle).get val cdata = vehicle.Definition.Packet.ConstructorData(vehicle).get
"VehicleService" should { "VehicleService" should {
@ -260,6 +262,7 @@ class TransferPassengerChannelTest extends ActorTest {
"pass TransferPassengerChannel" in { "pass TransferPassengerChannel" in {
val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service") val service = system.actorOf(Props(classOf[VehicleService], Zone.Nowhere), "v-service")
val fury = Vehicle(GlobalDefinitions.fury) val fury = Vehicle(GlobalDefinitions.fury)
fury.Actor = system.actorOf(Props(classOf[VehicleControl], fury), "test-fury")
service ! Service.Join("test") service ! Service.Join("test")
service ! VehicleServiceMessage("test", VehicleAction.TransferPassengerChannel(PlanetSideGUID(10), "old_channel", "new_channel", fury, PlanetSideGUID(11))) service ! VehicleServiceMessage("test", VehicleAction.TransferPassengerChannel(PlanetSideGUID(10), "old_channel", "new_channel", fury, PlanetSideGUID(11)))
expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11)))) expectMsg(VehicleServiceResponse("/test/Vehicle", PlanetSideGUID(10), VehicleResponse.TransferPassengerChannel("old_channel", "new_channel", fury, PlanetSideGUID(11))))

View file

@ -12,7 +12,7 @@ import MDCContextAware.Implicits._
import com.github.mauricio.async.db.general.ArrayRowData import com.github.mauricio.async.db.general.ArrayRowData
import com.github.mauricio.async.db.{Connection, QueryResult} import com.github.mauricio.async.db.{Connection, QueryResult}
import net.psforever.objects.Account import net.psforever.objects.Account
import net.psforever.objects.DefaultCancellable import net.psforever.objects.Default
import net.psforever.types.PlanetSideEmpire import net.psforever.types.PlanetSideEmpire
import net.psforever.WorldConfig import net.psforever.WorldConfig
import services.ServiceManager import services.ServiceManager
@ -40,9 +40,9 @@ class LoginSessionActor extends Actor with MDCContextAware {
var sessionId : Long = 0 var sessionId : Long = 0
var leftRef : ActorRef = ActorRef.noSender var leftRef : ActorRef = ActorRef.noSender
var rightRef : ActorRef = ActorRef.noSender var rightRef : ActorRef = ActorRef.noSender
var accountIntermediary : ActorRef = Actor.noSender var accountIntermediary : ActorRef = ActorRef.noSender
var updateServerListTask : Cancellable = DefaultCancellable.obj var updateServerListTask : Cancellable = Default.Cancellable
var ipAddress : String = "" var ipAddress : String = ""
var hostName : String = "" var hostName : String = ""

View file

@ -5,7 +5,7 @@ import scodec.Attempt.{Failure, Successful}
import scodec.bits._ import scodec.bits._
import org.log4s.MDC import org.log4s.MDC
import MDCContextAware.Implicits._ import MDCContextAware.Implicits._
import net.psforever.objects.DefaultCancellable import net.psforever.objects.Default
import net.psforever.packet.control.{HandleGamePacket, _} import net.psforever.packet.control.{HandleGamePacket, _}
import scala.annotation.tailrec import scala.annotation.tailrec
@ -52,7 +52,7 @@ class PacketCodingActor extends Actor with MDCContextAware {
// Due to the fact the client can send `RelatedA` packets out of order, we need to keep a buffer of which subslots arrived correctly, order them // Due to the fact the client can send `RelatedA` packets out of order, we need to keep a buffer of which subslots arrived correctly, order them
// and then act accordingly to send the missing subslot packet after a specified timeout // and then act accordingly to send the missing subslot packet after a specified timeout
private var relatedALog : ArrayBuffer[Int] = ArrayBuffer() private var relatedALog : ArrayBuffer[Int] = ArrayBuffer()
private var relatedABufferTimeout : Cancellable = DefaultCancellable.obj private var relatedABufferTimeout : Cancellable = Default.Cancellable
def AddSlottedPacketToLog(subslot: Int, packet : ByteVector): Unit = { def AddSlottedPacketToLog(subslot: Int, packet : ByteVector): Unit = {
val log_limit = 500 // Number of SlottedMetaPackets to keep in history val log_limit = 500 // Number of SlottedMetaPackets to keep in history
@ -386,7 +386,7 @@ class PacketCodingActor extends Actor with MDCContextAware {
// The client has indicated it's received up to a certain subslot, that means we can purge the log of any subslots prior to and including the confirmed subslot // The client has indicated it's received up to a certain subslot, that means we can purge the log of any subslots prior to and including the confirmed subslot
// Find where this subslot is stored in the packet log (if at all) and drop anything to the left of it, including itself // Find where this subslot is stored in the packet log (if at all) and drop anything to the left of it, including itself
if(relatedABufferTimeout.isCancelled || relatedABufferTimeout == DefaultCancellable.obj) { if(relatedABufferTimeout.isCancelled || relatedABufferTimeout == Default.Cancellable) {
val pos = slottedPacketLog.keySet.toArray.indexOf(subslot) val pos = slottedPacketLog.keySet.toArray.indexOf(subslot)
if(pos != -1) { if(pos != -1) {
slottedPacketLog = slottedPacketLog.drop(pos+1) slottedPacketLog = slottedPacketLog.drop(pos+1)

View file

@ -13,6 +13,7 @@ import ch.qos.logback.core.util.StatusPrinter
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import net.psforever.config.{Invalid, Valid} import net.psforever.config.{Invalid, Valid}
import net.psforever.crypto.CryptoInterface import net.psforever.crypto.CryptoInterface
import net.psforever.objects.Default
import net.psforever.objects.zones._ import net.psforever.objects.zones._
import net.psforever.objects.guid.TaskResolver import net.psforever.objects.guid.TaskResolver
import net.psforever.psadmin.PsAdminActor import net.psforever.psadmin.PsAdminActor
@ -225,6 +226,7 @@ object PsLogin {
/** Start up the main actor system. This "system" is the home for all actors running on this server */ /** Start up the main actor system. This "system" is the home for all actors running on this server */
system = ActorSystem("PsLogin") system = ActorSystem("PsLogin")
Default(system)
logger.info("Starting actor pipelines") logger.info("Starting actor pipelines")
/** Create pipelines for the login and world servers /** Create pipelines for the login and world servers

View file

@ -48,7 +48,7 @@ class SessionRouter(role : String, pipeline : List[SessionPipeline]) extends Act
val sessionById = mutable.Map[Long, Session]() val sessionById = mutable.Map[Long, Session]()
val sessionByActor = mutable.Map[ActorRef, Session]() val sessionByActor = mutable.Map[ActorRef, Session]()
val closePacket = PacketCoding.EncodePacket(ConnectionClose()).require.bytes val closePacket = PacketCoding.EncodePacket(ConnectionClose()).require.bytes
var accountIntermediary : ActorRef = Actor.noSender var accountIntermediary : ActorRef = ActorRef.noSender
var sessionId = 0L // this is a connection session, not an actual logged in session ID var sessionId = 0L // this is a connection session, not an actual logged in session ID
var inputRef : ActorRef = ActorRef.noSender var inputRef : ActorRef = ActorRef.noSender

View file

@ -25,7 +25,7 @@ class TcpListener[T <: Actor](actorClass : Class[T],
var sessionId = 0L var sessionId = 0L
var bytesRecevied = 0L var bytesRecevied = 0L
var bytesSent = 0L var bytesSent = 0L
var nextActor : ActorRef = Actor.noSender var nextActor : ActorRef = ActorRef.noSender
def receive = { def receive = {
case Tcp.Bound(local) => case Tcp.Bound(local) =>

View file

@ -38,7 +38,7 @@ class UdpListener(nextActorProps : Props,
var bytesRecevied = 0L var bytesRecevied = 0L
var bytesSent = 0L var bytesSent = 0L
var nextActor : ActorRef = Actor.noSender var nextActor : ActorRef = ActorRef.noSender
def receive = { def receive = {
case Udp.Bound(local) => case Udp.Bound(local) =>

View file

@ -5,10 +5,7 @@ import com.github.mauricio.async.db.general.ArrayRowData
import com.github.mauricio.async.db.{Connection, QueryResult} import com.github.mauricio.async.db.{Connection, QueryResult}
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import net.psforever.WorldConfig
import org.log4s.{Logger, MDC} import org.log4s.{Logger, MDC}
import scala.annotation.{switch, tailrec} import scala.annotation.{switch, tailrec}
import scala.collection.mutable.LongMap import scala.collection.mutable.LongMap
import scala.concurrent.{Await, Future, Promise} import scala.concurrent.{Await, Future, Promise}
@ -62,6 +59,7 @@ import net.psforever.packet.game._
import net.psforever.packet.game.objectcreate.{ConstructorData, DetailedCharacterData, DroppedItemData, ObjectClass, ObjectCreateMessageParent, PlacementData} import net.psforever.packet.game.objectcreate.{ConstructorData, DetailedCharacterData, DroppedItemData, ObjectClass, ObjectCreateMessageParent, PlacementData}
import net.psforever.packet.game.{HotSpotInfo => PacketHotSpotInfo} import net.psforever.packet.game.{HotSpotInfo => PacketHotSpotInfo}
import net.psforever.types._ import net.psforever.types._
import net.psforever.WorldConfig
import services.{RemoverActor, Service, ServiceManager} import services.{RemoverActor, Service, ServiceManager}
import services.account.{AccountPersistenceService, PlayerToken, ReceiveAccountData, RetrieveAccountData} import services.account.{AccountPersistenceService, PlayerToken, ReceiveAccountData, RetrieveAccountData}
import services.avatar.{AvatarAction, AvatarResponse, AvatarServiceMessage, AvatarServiceResponse} import services.avatar.{AvatarAction, AvatarResponse, AvatarServiceMessage, AvatarServiceResponse}
@ -89,8 +87,8 @@ class WorldSessionActor extends Actor
var chatService : ActorRef = ActorRef.noSender var chatService : ActorRef = ActorRef.noSender
var galaxyService : ActorRef = ActorRef.noSender var galaxyService : ActorRef = ActorRef.noSender
var squadService : ActorRef = ActorRef.noSender var squadService : ActorRef = ActorRef.noSender
var taskResolver : ActorRef = Actor.noSender var taskResolver : ActorRef = ActorRef.noSender
var cluster : ActorRef = Actor.noSender var cluster : ActorRef = ActorRef.noSender
var continent : Zone = Zone.Nowhere var continent : Zone = Zone.Nowhere
var account : Account = null var account : Account = null
var player : Player = null var player : Player = null
@ -163,9 +161,13 @@ class WorldSessionActor extends Actor
var squadSetup : () => Unit = FirstTimeSquadSetup var squadSetup : () => Unit = FirstTimeSquadSetup
var squadUpdateCounter : Int = 0 var squadUpdateCounter : Int = 0
val queuedSquadActions : Seq[() => Unit] = Seq(SquadUpdates, NoSquadUpdates, NoSquadUpdates, NoSquadUpdates) val queuedSquadActions : Seq[() => Unit] = Seq(SquadUpdates, NoSquadUpdates, NoSquadUpdates, NoSquadUpdates)
/** Keeps track of the number of PlayerStateMessageUpstream messages received by the client /** Upstream message counter<br>
* Checks for server acknowledgement of the following messages:<br>
* `PlayerStateMessageUpstream`<br>
* `VehicleStateMessage` (driver seat only)<br>
* `ChildObjectStateMessage` (any seat but driver)<br>
* As they should arrive roughly every 250 milliseconds this allows for a very crude method of scheduling tasks up to four times per second */ * As they should arrive roughly every 250 milliseconds this allows for a very crude method of scheduling tasks up to four times per second */
private var playerStateMessageUpstreamCount = 0 private var upstreamMessageCount : Int = 0
var zoningType : Zoning.Method.Value = Zoning.Method.None var zoningType : Zoning.Method.Value = Zoning.Method.None
var zoningChatMessageType : ChatMessageType.Value = ChatMessageType.CMT_QUIT var zoningChatMessageType : ChatMessageType.Value = ChatMessageType.CMT_QUIT
var zoningStatus : Zoning.Status.Value = Zoning.Status.None var zoningStatus : Zoning.Status.Value = Zoning.Status.None
@ -174,17 +176,26 @@ class WorldSessionActor extends Actor
lazy val unsignedIntMaxValue : Long = Int.MaxValue.toLong * 2L + 1L lazy val unsignedIntMaxValue : Long = Int.MaxValue.toLong * 2L + 1L
var serverTime : Long = 0 var serverTime : Long = 0
var amsSpawnPoints : List[SpawnPoint] = Nil var amsSpawnPoints : List[SpawnPoint] = Nil
/** a flag for the zone having finished loading during zoning
* `None` when no zone is loaded
* `Some(true)` when a zone has successfully loaded
* `Some(false)` when the loading process has failed or was executed but did not complete for some reason
* */
var zoneLoaded : Option[Boolean] = None
/** a flag that forces the current zone to reload itself during a zoning operation */
var zoneReload : Boolean = false
var turnCounter : PlanetSideGUID=>Unit = TurnCounterDuringInterim
var clientKeepAlive : Cancellable = DefaultCancellable.obj var clientKeepAlive : Cancellable = Default.Cancellable
var progressBarUpdate : Cancellable = DefaultCancellable.obj var progressBarUpdate : Cancellable = Default.Cancellable
var reviveTimer : Cancellable = DefaultCancellable.obj var reviveTimer : Cancellable = Default.Cancellable
var respawnTimer : Cancellable = DefaultCancellable.obj var respawnTimer : Cancellable = Default.Cancellable
var cargoMountTimer : Cancellable = DefaultCancellable.obj var cargoMountTimer : Cancellable = Default.Cancellable
var cargoDismountTimer : Cancellable = DefaultCancellable.obj var cargoDismountTimer : Cancellable = Default.Cancellable
var antChargingTick : Cancellable = DefaultCancellable.obj var antChargingTick : Cancellable = Default.Cancellable
var antDischargingTick : Cancellable = DefaultCancellable.obj var antDischargingTick : Cancellable = Default.Cancellable
var zoningTimer : Cancellable = DefaultCancellable.obj var zoningTimer : Cancellable = Default.Cancellable
var zoningReset : Cancellable = DefaultCancellable.obj var zoningReset : Cancellable = Default.Cancellable
/** /**
* Convert a boolean value into an integer value. * Convert a boolean value into an integer value.
* Use: `true:Int` or `false:Int` * Use: `true:Int` or `false:Int`
@ -832,14 +843,14 @@ class WorldSessionActor extends Actor
case Zone.Population.PlayerHasLeft(zone, Some(tplayer)) => case Zone.Population.PlayerHasLeft(zone, Some(tplayer)) =>
if(tplayer.isAlive) { if(tplayer.isAlive) {
log.info(s"$tplayer has left zone ${zone.Id}") log.info(s"${tplayer.Name} has left zone ${zone.Id}")
} }
case Zone.Population.PlayerCanNotSpawn(zone, tplayer) => case Zone.Population.PlayerCanNotSpawn(zone, tplayer) =>
log.warn(s"$tplayer can not spawn in zone ${zone.Id}; why?") log.warn(s"${tplayer.Name} can not spawn in zone ${zone.Id}; why?")
case Zone.Population.PlayerAlreadySpawned(zone, tplayer) => case Zone.Population.PlayerAlreadySpawned(zone, tplayer) =>
log.warn(s"$tplayer is already spawned on zone ${zone.Id}; a clerical error?") log.warn(s"${tplayer.Name} is already spawned on zone ${zone.Id}; a clerical error?")
case Zone.Lattice.SpawnPoint(zone_id, spawn_tube) => case Zone.Lattice.SpawnPoint(zone_id, spawn_tube) =>
CancelZoningProcess() CancelZoningProcess()
@ -917,7 +928,7 @@ class WorldSessionActor extends Actor
PutItemOnGround(item, pos, orient) PutItemOnGround(item, pos, orient)
case Zone.Ground.CanNotDropItem(zone, item, reason) => case Zone.Ground.CanNotDropItem(zone, item, reason) =>
log.warn(s"DropItem: $player tried to drop a $item on the ground, but $reason") log.warn(s"DropItem: ${player.Name} tried to drop a $item on the ground, but $reason")
if(!item.HasGUID) { if(!item.HasGUID) {
log.warn(s"DropItem: zone ${continent.Id} contents may be in disarray") log.warn(s"DropItem: zone ${continent.Id} contents may be in disarray")
} }
@ -951,9 +962,9 @@ class WorldSessionActor extends Actor
case Zone.Ground.CanNotPickupItem(zone, item_guid, _) => case Zone.Ground.CanNotPickupItem(zone, item_guid, _) =>
zone.GUID(item_guid) match { zone.GUID(item_guid) match {
case Some(item) => case Some(item) =>
log.warn(s"DropItem: finding a $item on the ground was suggested, but $player can not reach it") log.warn(s"DropItem: finding a $item on the ground was suggested, but ${player.Name} can not reach it")
case None => case None =>
log.warn(s"DropItem: finding an item ($item_guid) on the ground was suggested, but $player can not see it") log.warn(s"DropItem: finding an item ($item_guid) on the ground was suggested, but ${player.Name} can not see it")
sendResponse(ObjectDeleteMessage(item_guid, 0)) sendResponse(ObjectDeleteMessage(item_guid, 0))
} }
@ -1504,6 +1515,9 @@ class WorldSessionActor extends Actor
val weaponsEnabled = (continent.Map.Name != "map11" && continent.Map.Name != "map12" && continent.Map.Name != "map13") val weaponsEnabled = (continent.Map.Name != "map11" && continent.Map.Name != "map12" && continent.Map.Name != "map13")
sendResponse(LoadMapMessage(continent.Map.Name, continent.Id, 40100, 25, weaponsEnabled, continent.Map.Checksum)) sendResponse(LoadMapMessage(continent.Map.Name, continent.Id, 40100, 25, weaponsEnabled, continent.Map.Checksum))
setupAvatarFunc() //important! the LoadMapMessage must be processed by the client before the avatar is created setupAvatarFunc() //important! the LoadMapMessage must be processed by the client before the avatar is created
turnCounter = TurnCounterDuringInterim
context.system.scheduler.scheduleOnce(delay = 2000 millisecond, self, SetCurrentAvatar(tplayer, 200))
upstreamMessageCount = 0
persist() persist()
case PlayerLoaded(tplayer) => case PlayerLoaded(tplayer) =>
@ -1511,8 +1525,9 @@ class WorldSessionActor extends Actor
log.info(s"Player ${tplayer.Name} will respawn") log.info(s"Player ${tplayer.Name} will respawn")
player = tplayer player = tplayer
setupAvatarFunc() setupAvatarFunc()
upstreamMessageCount = 0
persist() persist()
self ! SetCurrentAvatar(tplayer) self ! SetCurrentAvatar(tplayer, 200)
case PlayerFailedToLoad(tplayer) => case PlayerFailedToLoad(tplayer) =>
player.Continent match { player.Continent match {
@ -1520,12 +1535,66 @@ class WorldSessionActor extends Actor
failWithError(s"${tplayer.Name} failed to load anywhere") failWithError(s"${tplayer.Name} failed to load anywhere")
} }
case SetCurrentAvatar(tplayer) => /*
if(tplayer.Actor == ActorRef.noSender) { The user is either already in the current zone and merely transporting himself from one location to another,
respawnTimer = context.system.scheduler.scheduleOnce(100 milliseconds, self, SetCurrentAvatar(tplayer)) also called "dying", or occasionally "deconstructing,"
or is completely switching in between zones.
These correspond to the message NewPlayerLoaded for the case of "dying" or the latter zone switching case,
and PlayerLoaded for "deconstruction."
In the latter case, the user must wait for the zone to be recognized as loaded for the server
and this is performed through the send LoadMapMessage, receive BeginZoningMessage exchange
The user's player should have already been registered into the new zone
and is at some stage of being added to the zone in which they will have control agency in that zone.
Whether or not the zone is loaded in the earlier case depends on the destination with respect to the current location.
Once all of the following is (assumed) accomplished,
the servwer will attempt to declare that user's player the avatar of the user's client.
Reception of certain packets that represent "reported user activity" after that marks the end of avatar loading.
If the maximum number of unsuccessful attempts is reached, some course of action is taken.
If the player dies, the process does not need to continue.
He may or may not be accompanied by a vehicle at any stage of this process.
*/
case SetCurrentAvatar(tplayer, max_attempts, attempt) =>
respawnTimer.cancel
val waitingOnUpstream = upstreamMessageCount == 0
if(attempt >= max_attempts && waitingOnUpstream) {
zoneLoaded match {
case None | Some(false) =>
log.warn("SetCurrentAvatar: failed to load intended destination zone; routing to faction sanctuary")
RequestSanctuaryZoneSpawn(tplayer, continent.Number)
case _ =>
log.warn("SetCurrentAvatar: the zone loaded but elements remain unready; restarting the process ...")
val pos = shiftPosition.getOrElse(player.Position)
val orient = shiftOrientation.getOrElse(player.Orientation)
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, pos, player.Faction, true))
val toZoneId = continent.Id
tplayer.Die
continent.Population ! Zone.Population.Leave(avatar) //does not matter if it doesn't work
zoneLoaded = None
zoneReload = true
LoadZonePhysicalSpawnPoint(toZoneId, pos, orient, respawnTime = 0L)
}
} }
else { else if(tplayer.isAlive) {
HandleSetCurrentAvatar(tplayer) if(
zoneLoaded.contains(true) &&
tplayer.HasGUID && tplayer.Actor != Default.Actor && (continent.GUID(tplayer.VehicleSeated) match {
case Some(o : Vehicle) => o.HasGUID && o.Actor != Default.Actor && !o.Destroyed
case _ => true
})
) {
if(waitingOnUpstream) {
beginZoningSetCurrentAvatarFunc(tplayer)
respawnTimer = context.system.scheduler.scheduleOnce(
delay = (if(attempt <= max_attempts / 2) 10 else 5) seconds,
self,
SetCurrentAvatar(tplayer, max_attempts, attempt + max_attempts / 3)
)
}
//if not the condition above, player has started playing normally
}
else {
respawnTimer = context.system.scheduler.scheduleOnce(500 milliseconds, self, SetCurrentAvatar(tplayer, max_attempts, attempt + 1))
}
} }
case NtuCharging(tplayer, vehicle) => case NtuCharging(tplayer, vehicle) =>
@ -1737,7 +1806,7 @@ class WorldSessionActor extends Actor
case _ => case _ =>
//fall back to sanctuary/prior? //fall back to sanctuary/prior?
log.error(s"LoginInfo: player $playerName could not be found in game world") log.error(s"LoginInfo: player ${player.Name}Name could not be found in game world")
self ! PlayerToken.LoginInfo(playerName, Zone.Nowhere, pos) self ! PlayerToken.LoginInfo(playerName, Zone.Nowhere, pos)
} }
@ -1898,7 +1967,7 @@ class WorldSessionActor extends Actor
/** /**
* Use the zoning process using some spawnable entity in the destination zone. * Use the zoning process using some spawnable entity in the destination zone.
* @param zone the destination zone * @param zone the destination zone
* @param spawnPosition the destination spawn position * @param spawnPosition the destination spawn position
* @param spawnOrientation the destination spawn orientation * @param spawnOrientation the destination spawn orientation
*/ */
@ -2586,7 +2655,7 @@ class WorldSessionActor extends Actor
CancelZoningProcessWithDescriptiveReason("cancel_mount") CancelZoningProcessWithDescriptiveReason("cancel_mount")
val obj_guid : PlanetSideGUID = obj.GUID val obj_guid : PlanetSideGUID = obj.GUID
val player_guid : PlanetSideGUID = tplayer.GUID val player_guid : PlanetSideGUID = tplayer.GUID
log.info(s"MountVehicleMsg: $player_guid mounts $obj_guid @ $seat_num") log.info(s"MountVehicleMsg: ${player.Name}_guid mounts $obj_guid @ $seat_num")
CancelAllProximityUnits() CancelAllProximityUnits()
sendResponse(PlanetsideAttributeMessage(obj_guid, 0, obj.Health)) sendResponse(PlanetsideAttributeMessage(obj_guid, 0, obj.Health))
sendResponse(PlanetsideAttributeMessage(obj_guid, 68, obj.Shields)) //shield health sendResponse(PlanetsideAttributeMessage(obj_guid, 68, obj.Shields)) //shield health
@ -2658,16 +2727,16 @@ class WorldSessionActor extends Actor
log.warn(s"DismountVehicleMsg: $obj is some generic mountable object and nothing will happen") log.warn(s"DismountVehicleMsg: $obj is some generic mountable object and nothing will happen")
case Mountable.CanNotMount(obj : Vehicle, seat_num) => case Mountable.CanNotMount(obj : Vehicle, seat_num) =>
log.warn(s"MountVehicleMsg: $tplayer attempted to mount $obj's seat $seat_num, but was not allowed") log.warn(s"MountVehicleMsg: ${tplayer.Name} attempted to mount $obj's seat $seat_num, but was not allowed")
if(obj.SeatPermissionGroup(seat_num).contains(AccessPermissionGroup.Driver)) { if(obj.SeatPermissionGroup(seat_num).contains(AccessPermissionGroup.Driver)) {
sendResponse(ChatMsg(ChatMessageType.CMT_OPEN, false, "", "You are not the driver of this vehicle.", None)) sendResponse(ChatMsg(ChatMessageType.CMT_OPEN, false, "", "You are not the driver of this vehicle.", None))
} }
case Mountable.CanNotMount(obj : Mountable, seat_num) => case Mountable.CanNotMount(obj : Mountable, seat_num) =>
log.warn(s"MountVehicleMsg: $tplayer attempted to mount $obj's seat $seat_num, but was not allowed") log.warn(s"MountVehicleMsg: ${tplayer.Name} attempted to mount $obj's seat $seat_num, but was not allowed")
case Mountable.CanNotDismount(obj, seat_num) => case Mountable.CanNotDismount(obj, seat_num) =>
log.warn(s"DismountVehicleMsg: $tplayer attempted to dismount $obj's seat $seat_num, but was not allowed") log.warn(s"DismountVehicleMsg: ${tplayer.Name} attempted to dismount $obj's seat $seat_num, but was not allowed")
} }
} }
@ -2866,7 +2935,7 @@ class WorldSessionActor extends Actor
lastTerminalOrderFulfillment = true lastTerminalOrderFulfillment = true
case Terminal.InfantryLoadout(exosuit, subtype, holsters, inventory) => case Terminal.InfantryLoadout(exosuit, subtype, holsters, inventory) =>
log.info(s"$tplayer wants to change equipment loadout to their option #${msg.unk1 + 1}") log.info(s"${tplayer.Name} wants to change equipment loadout to their option #${msg.unk1 + 1}")
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Loadout, true)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Loadout, true))
//sanitize exo-suit for change //sanitize exo-suit for change
val originalSuit = player.ExoSuit val originalSuit = player.ExoSuit
@ -2906,7 +2975,7 @@ class WorldSessionActor extends Actor
} }
} }
else { else {
log.warn(s"$tplayer no longer has permission to wear the exo-suit type $exosuit; will wear $fallbackSuit instead") log.warn(s"${tplayer.Name} no longer has permission to wear the exo-suit type $exosuit; will wear $fallbackSuit instead")
(fallbackSuit, fallbackSubtype) (fallbackSuit, fallbackSubtype)
} }
//update suit interally (holsters must be empty before this point) //update suit interally (holsters must be empty before this point)
@ -3014,7 +3083,7 @@ class WorldSessionActor extends Actor
lastTerminalOrderFulfillment = true lastTerminalOrderFulfillment = true
case Terminal.VehicleLoadout(definition, weapons, inventory) => case Terminal.VehicleLoadout(definition, weapons, inventory) =>
log.info(s"$tplayer wants to change their vehicle equipment loadout to their option #${msg.unk1 + 1}") log.info(s"${tplayer.Name} wants to change their vehicle equipment loadout to their option #${msg.unk1 + 1}")
FindLocalVehicle match { FindLocalVehicle match {
case Some(vehicle) => case Some(vehicle) =>
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Loadout, true)) sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Loadout, true))
@ -3112,7 +3181,7 @@ class WorldSessionActor extends Actor
case Terminal.LearnImplant(implant) => case Terminal.LearnImplant(implant) =>
val terminal_guid = msg.terminal_guid val terminal_guid = msg.terminal_guid
val implant_type = implant.Type val implant_type = implant.Type
val message = s"Implants: $tplayer wants to learn $implant_type" val message = s"Implants: ${tplayer.Name} wants to learn $implant_type"
val (interface, slotNumber) = tplayer.VehicleSeated match { val (interface, slotNumber) = tplayer.VehicleSeated match {
case Some(mech_guid) => case Some(mech_guid) =>
( (
@ -3166,13 +3235,13 @@ class WorldSessionActor extends Actor
} }
if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) { if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) {
val slot = slotNumber.get val slot = slotNumber.get
log.info(s"$tplayer is selling $implant_type - take from slot $slot") log.info(s"${tplayer.Name} is selling $implant_type - take from slot $slot")
player.Actor ! Player.UninitializeImplant(slot) player.Actor ! Player.UninitializeImplant(slot)
sendResponse(AvatarImplantMessage(tplayer.GUID, ImplantAction.Remove, slot, 0)) sendResponse(AvatarImplantMessage(tplayer.GUID, ImplantAction.Remove, slot, 0))
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, true)) sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, true))
} }
else { else {
val message = s"$tplayer can not sell $implant_type" val message = s"${tplayer.Name} can not sell $implant_type"
if(interface.isEmpty) { if(interface.isEmpty) {
log.warn(s"$message - not interacting with a terminal") log.warn(s"$message - not interacting with a terminal")
} }
@ -3230,7 +3299,7 @@ class WorldSessionActor extends Actor
} }
case None => case None =>
log.error(s"$tplayer wanted to spawn a vehicle, but there was no spawn pad associated with terminal ${msg.terminal_guid} to accept it") log.error(s"${tplayer.Name} wanted to spawn a vehicle, but there was no spawn pad associated with terminal ${msg.terminal_guid} to accept it")
} }
lastTerminalOrderFulfillment = true lastTerminalOrderFulfillment = true
@ -3764,6 +3833,7 @@ class WorldSessionActor extends Actor
//player died during setup; probably a relog //player died during setup; probably a relog
player.Actor ! Player.Die() player.Actor ! Player.Die()
} }
upstreamMessageCount = 0
} }
/** /**
@ -3772,7 +3842,7 @@ class WorldSessionActor extends Actor
* @param tplayer the target player * @param tplayer the target player
*/ */
def SetCurrentAvatarNormally(tplayer : Player) : Unit = { def SetCurrentAvatarNormally(tplayer : Player) : Unit = {
self ! SetCurrentAvatar(tplayer) HandleSetCurrentAvatar(tplayer)
} }
/** /**
@ -3787,6 +3857,7 @@ class WorldSessionActor extends Actor
*/ */
def SetCurrentAvatarUponDeployment(tplayer : Player) : Unit = { def SetCurrentAvatarUponDeployment(tplayer : Player) : Unit = {
beginZoningSetCurrentAvatarFunc = SetCurrentAvatarNormally beginZoningSetCurrentAvatarFunc = SetCurrentAvatarNormally
upstreamMessageCount = 0
continent.Actor ! Zone.Lattice.RequestSpawnPoint(continent.Number, tplayer, 0) continent.Actor ! Zone.Lattice.RequestSpawnPoint(continent.Number, tplayer, 0)
} }
@ -4061,6 +4132,7 @@ class WorldSessionActor extends Actor
case msg@BeginZoningMessage() => case msg@BeginZoningMessage() =>
log.info("Reticulating splines ...") log.info("Reticulating splines ...")
zoneLoaded = None
val continentId = continent.Id val continentId = continent.Id
traveler.zone = continentId traveler.zone = continentId
val faction = player.Faction val faction = player.Faction
@ -4358,7 +4430,8 @@ class WorldSessionActor extends Actor
} }
} }
continent.VehicleEvents ! VehicleServiceMessage(continent.Id, VehicleAction.UpdateAmsSpawnPoint(continent)) continent.VehicleEvents ! VehicleServiceMessage(continent.Id, VehicleAction.UpdateAmsSpawnPoint(continent))
beginZoningSetCurrentAvatarFunc(player) upstreamMessageCount = 0
zoneLoaded = Some(true)
case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, yaw, pitch, yaw_upper, seq_time, unk3, is_crouching, is_jumping, jump_thrust, is_cloaking, unk5, unk6) => case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, yaw, pitch, yaw_upper, seq_time, unk3, is_crouching, is_jumping, jump_thrust, is_cloaking, unk5, unk6) =>
if (player.death_by == -1) { if (player.death_by == -1) {
@ -4366,14 +4439,14 @@ class WorldSessionActor extends Actor
Thread.sleep(300) Thread.sleep(300)
sendResponse(DropSession(sessionId, "kick by GM")) sendResponse(DropSession(sessionId, "kick by GM"))
} }
playerStateMessageUpstreamCount += 1 turnCounter(avatar_guid)
val isMoving = WorldEntity.isMoving(vel) val isMoving = WorldEntity.isMoving(vel)
val isMovingPlus = isMoving || is_jumping || jump_thrust val isMovingPlus = isMoving || is_jumping || jump_thrust
if(isMovingPlus) { if(isMovingPlus) {
CancelZoningProcessWithDescriptiveReason("cancel_motion") CancelZoningProcessWithDescriptiveReason("cancel_motion")
} }
if(deadState == DeadState.Alive && playerStateMessageUpstreamCount % 2 == 0) { // Regen stamina roughly every 500ms if(deadState == DeadState.Alive && upstreamMessageCount % 2 == 0) { // Regen stamina roughly every 500ms
if(player.skipStaminaRegenForTurns > 0) { if(player.skipStaminaRegenForTurns > 0) {
//do not renew stamina for a while //do not renew stamina for a while
player.skipStaminaRegenForTurns -= 1 player.skipStaminaRegenForTurns -= 1
@ -4432,7 +4505,15 @@ class WorldSessionActor extends Actor
case msg@ChildObjectStateMessage(object_guid, pitch, yaw) => case msg@ChildObjectStateMessage(object_guid, pitch, yaw) =>
//the majority of the following check retrieves information to determine if we are in control of the child //the majority of the following check retrieves information to determine if we are in control of the child
FindContainedWeapon match { FindContainedWeapon match {
case (Some(_), Some(tool)) => case (Some(o), Some(tool)) =>
(o match {
case mount : Mountable => mount.PassengerInSeat(player)
case _ => None
}) match {
case None | Some(0) => ;
case Some(_) =>
turnCounter(player.GUID)
}
if(tool.GUID == object_guid) { if(tool.GUID == object_guid) {
//TODO set tool orientation? //TODO set tool orientation?
player.Orientation = Vector3(0f, pitch, yaw) player.Orientation = Vector3(0f, pitch, yaw)
@ -4445,7 +4526,7 @@ class WorldSessionActor extends Actor
log.warn(s"ChildObjectState: ${player.Name} can not find any controllable agent, let alone #${object_guid.guid}") log.warn(s"ChildObjectState: ${player.Name} can not find any controllable agent, let alone #${object_guid.guid}")
case (None, _) => ; case (None, _) => ;
//TODO status condition of "playing getting out of vehicle to allow for late packets without warning //TODO status condition of "playing getting out of vehicle to allow for late packets without warning
//log.warn(s"ChildObjectState: player $player not related to anything with a controllable agent") //log.warn(s"ChildObjectState: player ${player.Name} not related to anything with a controllable agent")
} }
if (player.death_by == -1) { if (player.death_by == -1) {
sendResponse(ChatMsg(ChatMessageType.UNK_71, true, "", "Your account has been logged out by a Customer Service Representative.", None)) sendResponse(ChatMsg(ChatMessageType.UNK_71, true, "", "Your account has been logged out by a Customer Service Representative.", None))
@ -4457,8 +4538,9 @@ class WorldSessionActor extends Actor
if(deadState == DeadState.Alive) { if(deadState == DeadState.Alive) {
GetVehicleAndSeat() match { GetVehicleAndSeat() match {
case (Some(obj), Some(0)) => case (Some(obj), Some(0)) =>
val seat = obj.Seats(0)
//we're driving the vehicle //we're driving the vehicle
turnCounter(player.GUID)
val seat = obj.Seats(0)
player.Position = pos //convenient player.Position = pos //convenient
if(seat.ControlledWeapon.isEmpty) { if(seat.ControlledWeapon.isEmpty) {
player.Orientation = Vector3.z(ang.z) //convenient player.Orientation = Vector3.z(ang.z) //convenient
@ -4503,7 +4585,7 @@ class WorldSessionActor extends Actor
} }
case msg@VehicleSubStateMessage(vehicle_guid, player_guid, vehicle_pos, vehicle_ang, vel, unk1, unk2) => case msg@VehicleSubStateMessage(vehicle_guid, player_guid, vehicle_pos, vehicle_ang, vel, unk1, unk2) =>
//log.info(s"VehicleSubState: $vehicle_guid, $player_guid, $vehicle_pos, $vehicle_ang, $vel, $unk1, $unk2") //log.info(s"VehicleSubState: $vehicle_guid, ${player.Name}_guid, $vehicle_pos, $vehicle_ang, $vel, $unk1, $unk2")
case msg@ProjectileStateMessage(projectile_guid, shot_pos, shot_vel, shot_orient, seq, end, target_guid) => case msg@ProjectileStateMessage(projectile_guid, shot_pos, shot_vel, shot_orient, seq, end, target_guid) =>
//log.trace(s"ProjectileState: $msg") //log.trace(s"ProjectileState: $msg")
@ -5207,13 +5289,13 @@ class WorldSessionActor extends Actor
continent.Ground ! Zone.Ground.DropItem(item, player.Position, player.Orientation) continent.Ground ! Zone.Ground.DropItem(item, player.Position, player.Orientation)
} }
case None => case None =>
log.warn(s"DropItem: $player wanted to drop a $anItem, but it wasn't at hand") log.warn(s"DropItem: ${player.Name} wanted to drop a $anItem, but it wasn't at hand")
} }
case Some(obj) => //TODO LLU case Some(obj) => //TODO LLU
log.warn(s"DropItem: $player wanted to drop a $obj, but that isn't possible") log.warn(s"DropItem: ${player.Name} wanted to drop a $obj, but that isn't possible")
case None => case None =>
sendResponse(ObjectDeleteMessage(item_guid, 0)) //this is fine; item doesn't exist to the server anyway sendResponse(ObjectDeleteMessage(item_guid, 0)) //this is fine; item doesn't exist to the server anyway
log.warn(s"DropItem: $player wanted to drop an item ($item_guid), but it was nowhere to be found") log.warn(s"DropItem: ${player.Name} wanted to drop an item ($item_guid), but it was nowhere to be found")
} }
case msg@PickupItemMessage(item_guid, player_guid, unk1, unk2) => case msg@PickupItemMessage(item_guid, player_guid, unk1, unk2) =>
@ -5227,7 +5309,7 @@ class WorldSessionActor extends Actor
sendResponse(ActionResultMessage.Fail(16)) //error code? sendResponse(ActionResultMessage.Fail(16)) //error code?
} }
case _ => case _ =>
log.warn(s"PickupItem: $player requested an item that doesn't exist in this zone; assume client-side garbage data") log.warn(s"PickupItem: ${player.Name} requested an item that doesn't exist in this zone; assume client-side garbage data")
sendResponse(ObjectDeleteMessage(item_guid, 0)) sendResponse(ObjectDeleteMessage(item_guid, 0))
} }
@ -5288,7 +5370,7 @@ class WorldSessionActor extends Actor
val before = player.DrawnSlot val before = player.DrawnSlot
if(before != held_holsters) { if(before != held_holsters) {
if(player.ExoSuit == ExoSuitType.MAX && held_holsters != 0) { if(player.ExoSuit == ExoSuitType.MAX && held_holsters != 0) {
log.info(s"ObjectHeld: $player is denied changing hands to $held_holsters as a MAX") log.info(s"ObjectHeld: ${player.Name} is denied changing hands to $held_holsters as a MAX")
player.DrawnSlot = 0 player.DrawnSlot = 0
sendResponse(ObjectHeldMessage(avatar_guid, 0, true)) sendResponse(ObjectHeldMessage(avatar_guid, 0, true))
} }
@ -5603,7 +5685,7 @@ class WorldSessionActor extends Actor
CancelZoningProcessWithDescriptiveReason("cancel_use") CancelZoningProcessWithDescriptiveReason("cancel_use")
if(obj.isBackpack) { if(obj.isBackpack) {
if(equipment.isEmpty) { if(equipment.isEmpty) {
log.info(s"UseItem: $player looting the corpse of $obj") log.info(s"UseItem: ${player.Name} looting the corpse of $obj")
sendResponse(UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType)) sendResponse(UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType))
accessedContainer = Some(obj) accessedContainer = Some(obj)
} }
@ -5716,7 +5798,7 @@ class WorldSessionActor extends Actor
CancelZoningProcessWithDescriptiveReason("cancel_use") CancelZoningProcessWithDescriptiveReason("cancel_use")
locker.Actor ! CommonMessages.Use(player, Some(item)) locker.Actor ! CommonMessages.Use(player, Some(item))
case None if locker.Faction == player.Faction || !locker.HackedBy.isEmpty => case None if locker.Faction == player.Faction || !locker.HackedBy.isEmpty =>
log.trace(s"UseItem: $player accessing a locker") log.trace(s"UseItem: ${player.Name} accessing a locker")
CancelZoningProcessWithDescriptiveReason("cancel_use") CancelZoningProcessWithDescriptiveReason("cancel_use")
val container = player.Locker val container = player.Locker
accessedContainer = Some(container) accessedContainer = Some(container)
@ -6208,7 +6290,7 @@ class WorldSessionActor extends Actor
} }
} }
else { else {
log.warn(s"WeaponFireMessage: $player's ${tool.Definition.Name} projectile is too far from owner position at time of discharge ($distanceToOwner > $acceptableDistanceToOwner); suspect") log.warn(s"WeaponFireMessage: ${player.Name}'s ${tool.Definition.Name} projectile is too far from owner position at time of discharge ($distanceToOwner > $acceptableDistanceToOwner); suspect")
} }
} }
case _ => ; case _ => ;
@ -6370,7 +6452,7 @@ class WorldSessionActor extends Actor
case out @ Some(_ : Mountable) => case out @ Some(_ : Mountable) =>
out out
case _ => case _ =>
dismountWarning(s"DismountVehicleMsg: player $player_guid not considered seated in a mountable entity") dismountWarning(s"DismountVehicleMsg: player ${player.Name}_guid not considered seated in a mountable entity")
None None
}) match { }) match {
case Some(obj : Mountable) => case Some(obj : Mountable) =>
@ -6395,7 +6477,7 @@ class WorldSessionActor extends Actor
} }
case None => case None =>
dismountWarning(s"DismountVehicleMsg: can not find where player $player_guid is seated in mountable ${player.VehicleSeated}") dismountWarning(s"DismountVehicleMsg: can not find where player ${player.Name}_guid is seated in mountable ${player.VehicleSeated}")
} }
case _ => case _ =>
dismountWarning(s"DismountVehicleMsg: can not find mountable entity ${player.VehicleSeated}") dismountWarning(s"DismountVehicleMsg: can not find mountable entity ${player.VehicleSeated}")
@ -6418,17 +6500,17 @@ class WorldSessionActor extends Actor
case Some(seat_num : Int) => case Some(seat_num : Int) =>
obj.Actor ! Mountable.TryDismount(tplayer, seat_num) obj.Actor ! Mountable.TryDismount(tplayer, seat_num)
case None => case None =>
dismountWarning(s"DismountVehicleMsg: can not find where other player $player_guid is seated in mountable $obj_guid") dismountWarning(s"DismountVehicleMsg: can not find where other player ${player.Name}_guid is seated in mountable $obj_guid")
} }
case (None, _) => ; case (None, _) => ;
log.warn(s"DismountVehicleMsg: $player can not find his vehicle") log.warn(s"DismountVehicleMsg: ${player.Name} can not find his vehicle")
case (_, None) => ; case (_, None) => ;
log.warn(s"DismountVehicleMsg: player $player_guid could not be found to kick") log.warn(s"DismountVehicleMsg: player ${player.Name}_guid could not be found to kick")
case _ => case _ =>
log.warn(s"DismountVehicleMsg: object is either not a Mountable or not a Player") log.warn(s"DismountVehicleMsg: object is either not a Mountable or not a Player")
} }
case None => case None =>
log.warn(s"DismountVehicleMsg: $player does not own a vehicle") log.warn(s"DismountVehicleMsg: ${player.Name} does not own a vehicle")
} }
} }
@ -6445,7 +6527,7 @@ class WorldSessionActor extends Actor
} }
} }
else { else {
log.warn(s"DeployRequest: $player does not own the deploying $vehicle_guid object") log.warn(s"DeployRequest: ${player.Name} does not own the deploying $vehicle_guid object")
} }
case msg @ AvatarGrenadeStateMessage(player_guid, state) => case msg @ AvatarGrenadeStateMessage(player_guid, state) =>
@ -6523,7 +6605,7 @@ class WorldSessionActor extends Actor
} }
} }
else { else {
log.warn(s"Vehicle attributes: $player does not own vehicle ${vehicle.GUID} and can not change it") log.warn(s"Vehicle attributes: ${player.Name} does not own vehicle ${vehicle.GUID} and can not change it")
} }
case _ => case _ =>
log.warn(s"echo unknown attributes behavior") log.warn(s"echo unknown attributes behavior")
@ -9320,7 +9402,7 @@ class WorldSessionActor extends Actor
val player_guid : PlanetSideGUID = tplayer.GUID val player_guid : PlanetSideGUID = tplayer.GUID
val obj_guid : PlanetSideGUID = obj.GUID val obj_guid : PlanetSideGUID = obj.GUID
PlayerActionsToCancel() PlayerActionsToCancel()
log.info(s"MountVehicleMsg: $player_guid mounts $obj @ $seatNum") log.info(s"MountVehicleMsg: ${player.Name}_guid mounts $obj @ $seatNum")
sendResponse(ObjectAttachMessage(obj_guid, player_guid, seatNum)) sendResponse(ObjectAttachMessage(obj_guid, player_guid, seatNum))
continent.VehicleEvents ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seatNum)) continent.VehicleEvents ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seatNum))
} }
@ -9353,7 +9435,7 @@ class WorldSessionActor extends Actor
def HandleDealingDamage(target : PlanetSideGameObject with Vitality, data : ResolvedProjectile) : Unit = { def HandleDealingDamage(target : PlanetSideGameObject with Vitality, data : ResolvedProjectile) : Unit = {
val func = data.damage_model.Calculate(data) val func = data.damage_model.Calculate(data)
target match { target match {
case obj : Player if obj.CanDamage && obj.Actor != ActorRef.noSender => case obj : Player if obj.CanDamage && obj.Actor != Default.Actor =>
if(obj.spectator) { if(obj.spectator) {
player.death_by = -1 // little thing for auto kick player.death_by = -1 // little thing for auto kick
} }
@ -10006,7 +10088,7 @@ class WorldSessionActor extends Actor
* @return a tuple composed of an `ActorRef` destination and a message to send to that destination * @return a tuple composed of an `ActorRef` destination and a message to send to that destination
*/ */
def LoadZoneAsPlayer(tplayer : Player, zone_id : String) : (ActorRef, Any) = { def LoadZoneAsPlayer(tplayer : Player, zone_id : String) : (ActorRef, Any) = {
if(zone_id == continent.Id) { if(!zoneReload && zone_id == continent.Id) {
if(player.isBackpack) { //important! test the actor-wide player ref, not the parameter if(player.isBackpack) { //important! test the actor-wide player ref, not the parameter
//respawning from unregistered player //respawning from unregistered player
(taskResolver, RegisterAvatar(tplayer)) (taskResolver, RegisterAvatar(tplayer))
@ -10115,7 +10197,7 @@ class WorldSessionActor extends Actor
continent.VehicleEvents ! VehicleServiceMessage(name, VehicleAction.TransferPassengerChannel(pguid, s"${cargo.Actor}", toChannel, cargo, topLevel)) continent.VehicleEvents ! VehicleServiceMessage(name, VehicleAction.TransferPassengerChannel(pguid, s"${cargo.Actor}", toChannel, cargo, topLevel))
} }
// //
if(zone_id == continent.Id) { if(!zoneReload && zone_id == continent.Id) {
if(vehicle.Definition == GlobalDefinitions.droppod) { if(vehicle.Definition == GlobalDefinitions.droppod) {
//instant action droppod in the same zone //instant action droppod in the same zone
(taskResolver, RegisterDroppod(vehicle, player)) (taskResolver, RegisterDroppod(vehicle, player))
@ -10175,7 +10257,7 @@ class WorldSessionActor extends Actor
**/ **/
def LoadZoneInVehicleAsPassenger(vehicle : Vehicle, zone_id : String) : (ActorRef, Any) = { def LoadZoneInVehicleAsPassenger(vehicle : Vehicle, zone_id : String) : (ActorRef, Any) = {
log.info(s"LoadZoneInVehicleAsPassenger: ${player.Name} is the passenger of a ${vehicle.Definition.Name}") log.info(s"LoadZoneInVehicleAsPassenger: ${player.Name} is the passenger of a ${vehicle.Definition.Name}")
if(zone_id == continent.Id) { if(!zoneReload && zone_id == continent.Id) {
//transferring a vehicle between spawn points (warp gates) in the same zone //transferring a vehicle between spawn points (warp gates) in the same zone
(self, PlayerLoaded(player)) (self, PlayerLoaded(player))
} }
@ -10226,9 +10308,11 @@ class WorldSessionActor extends Actor
* It also sets up actions for the new zone loading process. * It also sets up actions for the new zone loading process.
*/ */
def LoadZoneCommonTransferActivity() : Unit = { def LoadZoneCommonTransferActivity() : Unit = {
zoneLoaded = None
zoneReload = false
if(player.VehicleOwned.nonEmpty && player.VehicleSeated != player.VehicleOwned) { if(player.VehicleOwned.nonEmpty && player.VehicleSeated != player.VehicleOwned) {
continent.GUID(player.VehicleOwned) match { continent.GUID(player.VehicleOwned) match {
case Some(vehicle : Vehicle) if vehicle.Actor != ActorRef.noSender => case Some(vehicle : Vehicle) if vehicle.Actor != Default.Actor =>
vehicle.Actor ! Vehicle.Ownership(None) vehicle.Actor ! Vehicle.Ownership(None)
case _ => ; case _ => ;
} }
@ -11427,6 +11511,35 @@ class WorldSessionActor extends Actor
} }
} }
/**
* The upstream counter accumulates when the server receives sp[ecific messages from the client.
* It counts upwards until it reach maximum value, and then starts over.
* When it starts over, which should take an exceptionally long time to achieve,
* it starts counting at one rather than zero.
* @param p the player's globally unique identifier number
*/
def NormalTurnCounter(p : PlanetSideGUID) : Unit = {
upstreamMessageCount = 1 + upstreamMessageCount % Int.MaxValue
}
/**
* During the interim period between the avatar being in one place/zone
* and completing the process of transitioning to another place/zone,
* the upstream message counter is zero'd
* awaiting new activity from the client.
* Until new upstream messages that pass some tests against their data start being reported,
* the counter does not accumulate properly.
* @param guid the player's globally unique identifier number
*/
def TurnCounterDuringInterim(guid : PlanetSideGUID) : Unit = {
if(player.GUID == guid && player.Zone == continent) {
turnCounter = NormalTurnCounter
}
else {
upstreamMessageCount = 0
}
}
def failWithError(error : String) = { def failWithError(error : String) = {
log.error(error) log.error(error)
sendResponse(ConnectionClose()) sendResponse(ConnectionClose())
@ -11553,7 +11666,7 @@ object WorldSessionActor {
private final case class PlayerFailedToLoad(tplayer : Player) private final case class PlayerFailedToLoad(tplayer : Player)
private final case class CreateCharacter(name : String, head : Int, voice : CharacterVoice.Value, gender : CharacterGender.Value, empire : PlanetSideEmpire.Value) private final case class CreateCharacter(name : String, head : Int, voice : CharacterVoice.Value, gender : CharacterGender.Value, empire : PlanetSideEmpire.Value)
private final case class ListAccountCharacters() private final case class ListAccountCharacters()
private final case class SetCurrentAvatar(tplayer : Player) private final case class SetCurrentAvatar(tplayer : Player, max_attempts : Int, attempt : Int = 0)
private final case class ZoningReset() private final case class ZoningReset()
final val ftes = ( final val ftes = (