corrected an oversight where filter guids were being ignored and sameness between destination and filter was being ignored, by rewriting how actor Receive guard booleans are guards

This commit is contained in:
Fate-JH 2026-06-15 16:39:35 -04:00
parent 9d2d1cae9f
commit 3937bb8455
11 changed files with 242 additions and 203 deletions

View file

@ -3,7 +3,7 @@ package net.psforever.actors.session
import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware, typed} import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware, typed}
import net.psforever.actors.session.normal.NormalMode import net.psforever.actors.session.normal.NormalMode
import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerFunctionsBase, CommonHandlerLogic, ZoningOperations} import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerLogic, ZoningOperations}
import net.psforever.objects.TurretDeployable import net.psforever.objects.TurretDeployable
import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.serverobject.containable.Containable import net.psforever.objects.serverobject.containable.Containable
@ -95,6 +95,17 @@ object SessionActor {
private final case object PokeClient extends Command private final case object PokeClient extends Command
final case class SetMode(mode: PlayerMode) extends Command final case class SetMode(mode: PlayerMode) extends Command
private def HandlerAcceptingMessageTest(reply: Any)(handler: CommonHandlerFunctions): Boolean = {
if (handler.IgnoreFilter) {
false
} else {
handler.IgnoreFilter = true
val result = handler.isDefinedAt(reply)
handler.IgnoreFilter = false
result
}
}
} }
class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], connectionId: String, sessionId: Long) class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], connectionId: String, sessionId: Long)
@ -392,30 +403,31 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
case unknownStamp => case unknownStamp =>
log.error(s"received a message from an unknown event system - reply: $envelope, stamp: $unknownStamp") log.error(s"received a message from an unknown event system - reply: $envelope, stamp: $unknownStamp")
} }
println(s"event-system-rtt: ${System.currentTimeMillis() - envelope.time} ms") //println(s"event-system-rtt: ${System.currentTimeMillis() - envelope.time} ms")
} }
private def handleEnvelopeWithResponseHandler( private def handleEnvelopeWithResponseHandler(
responseHandler: CommonHandlerFunctionsBase, responseHandler: CommonHandlerFunctions,
envelope: GenericResponseEnvelope envelope: GenericResponseEnvelope
): Unit = { ): Unit = {
val GenericResponseEnvelope(toChannel, guid, reply) = envelope val GenericResponseEnvelope(toChannel, guid, reply) = envelope
//try the expected handler with the input response //try the expected handler with the input response
if (!responseHandler.handle(toChannel, guid, reply)) { if (!responseHandler.handle(toChannel, guid, reply)) {
//find any handler that might receive the response (ignore guard booleans during search) //test the expected handler again, ignoring guard booleans; if it would have been handled, stop with this
data.handlerFilter.set(guid, guid, notSame = true, same = true) responseHandler.IgnoreFilter = true
if (!responseHandler.isDefinedAt(reply)) { if (!responseHandler.isDefinedAt(reply)) {
listOfHandlers.filter(_.isDefinedAt(reply)) match { //find every handler that might accept the input response, ignoring guard booleans only for the search
//try each discovered handler with the input response
listOfHandlers.filter(SessionActor.HandlerAcceptingMessageTest(reply)) match {
case Nil => case Nil =>
log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}")
case first :: Nil => case first :: Nil =>
first.handle(toChannel, guid, reply) first.handle(toChannel, guid, reply)
case first :: others => case first :: others =>
if (!first.handle(toChannel, guid, reply)) { first.handle(toChannel, guid, reply) || others.exists(_.handle(toChannel, guid, reply))
others.find(_.tryToHandle(reply))
}
} }
} }
responseHandler.IgnoreFilter = false
} }
} }

View file

@ -45,7 +45,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
def receive: Receive = { def receive: Receive = {
/* special messages */ /* special messages */
case AvatarAction.TeardownConnection if player.spectator => case AvatarAction.TeardownConnection
if TestFilter(_ => { player.spectator }) =>
context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode) context.self ! SessionActor.SetMode(CustomerServiceRepresentativeMode)
context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection)) context.self.forward(GenericResponseEnvelope(AvatarStamp, "", filterGuid, AvatarAction.TeardownConnection))
@ -67,7 +68,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
isCloaking, isCloaking,
isNotRendered, isNotRendered,
canSeeReallyFar canSeeReallyFar
) if isNotSameTarget => ) if TestFilter(_ => isNotSameTarget) =>
val pstateToSave = pstate.copy(timestamp = 0) val pstateToSave = pstate.copy(timestamp = 0)
val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filterGuid.guid) match { val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filterGuid.guid) match {
case Some(SessionAvatarHandlers.LastUpstream(Some(msg), visible, shooting, time)) => (Some(msg), time, msg.pos, visible, shooting) case Some(SessionAvatarHandlers.LastUpstream(Some(msg), visible, shooting, time)) => (Some(msg), time, msg.pos, visible, shooting)
@ -155,7 +156,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value)
if value == ImplantType.SecondWind.value => if TestFilter(_ => { value == ImplantType.SecondWind.value }) =>
sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Add, implant_slot, 7)) sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Add, implant_slot, 7))
//second wind does not normally load its icon into the shortcut hotbar //second wind does not normally load its icon into the shortcut hotbar
avatar avatar
@ -167,7 +168,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value)
if value == ImplantType.SecondWind.value => if TestFilter(_ => { value == ImplantType.SecondWind.value }) =>
sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Remove, implant_slot, value)) sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Remove, implant_slot, value))
//second wind does not normally unload its icon from the shortcut hotbar //second wind does not normally unload its icon from the shortcut hotbar
val shortcut = { val shortcut = {
@ -186,7 +187,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value))
case AvatarAction.ObjectHeld(slot, _) case AvatarAction.ObjectHeld(slot, _)
if isSameTarget && player.VisibleSlots.contains(slot) => if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) =>
sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true))
//Stop using proximity terminals if player unholsters a weapon //Stop using proximity terminals if player unholsters a weapon
continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect {
@ -197,31 +198,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.ObjectHeld(slot, _) case AvatarAction.ObjectHeld(slot, _)
if isSameTarget && slot > -1 => if TestFilter(_ => {isSameTarget && slot > -1 }) =>
sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true))
case AvatarAction.ObjectHeld(_, _) case AvatarAction.ObjectHeld(_, _)
if isSameTarget => () if TestFilter(_ => isSameTarget) => ()
case AvatarAction.ObjectHeld(_, previousSlot) => case AvatarAction.ObjectHeld(_, previousSlot) =>
sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false))
case ChangeFireState_Start(weaponGuid) case ChangeFireState_Start(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
sendResponse(ChangeFireStateMessage_Start(weaponGuid)) sendResponse(ChangeFireStateMessage_Start(weaponGuid))
val entry = ops.lastSeenStreamMessage(filterGuid.guid) val entry = ops.lastSeenStreamMessage(filterGuid.guid)
ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid))) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid)))
case ChangeFireState_Stop(weaponGuid) case ChangeFireState_Stop(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) =>
sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
val entry = ops.lastSeenStreamMessage(filterGuid.guid) val entry = ops.lastSeenStreamMessage(filterGuid.guid)
ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None))
case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => case AvatarAction.LoadCreatedPlayer(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => case AvatarAction.EquipmentCreatedInHand(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.Destroy(victim, killer, weapon, pos) => case AvatarAction.Destroy(victim, killer, weapon, pos) =>
@ -232,7 +235,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk))
case AvatarAction.TerminalOrderResult(terminalGuid, action, result) case AvatarAction.TerminalOrderResult(terminalGuid, action, result)
if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => if TestFilter(_ => { result && (action == TransactionType.Buy || action == TransactionType.Loadout) }) =>
sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sendResponse(ItemTransactionResultMessage(terminalGuid, action, result))
sessionLogic.terminals.lastTerminalOrderFulfillment = true sessionLogic.terminals.lastTerminalOrderFulfillment = true
AvatarActor.savePlayerData(player) AvatarActor.savePlayerData(player)
@ -254,7 +257,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
inventory, inventory,
drop, drop,
delete delete
) if resolvedGuid == target => ) if TestFilter(_ => {resolvedGuid == target }) =>
sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(ArmorChangedMessage(target, exosuit, subtype))
sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor))
//happening to this player //happening to this player
@ -336,7 +339,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
oldInventory, oldInventory,
inventory, inventory,
drops drops
) if resolvedGuid == target => ) if TestFilter(_ => { resolvedGuid == target }) =>
sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(ArmorChangedMessage(target, exosuit, subtype))
sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor))
//happening to this player //happening to this player
@ -398,7 +401,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
/* common messages (maybe once every respawn) */ /* common messages (maybe once every respawn) */
case ReloadTool(itemGuid) case ReloadTool(itemGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
case AvatarAction.Killed(_, mount) => case AvatarAction.Killed(_, mount) =>
@ -438,11 +441,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
//render //render
CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player) CustomerServiceRepresentativeMode.renderPlayer(sessionLogic, continent, player)
case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => case AvatarAction.ReleasePlayer(tplayer)
if TestFilter(_ => isNotSameTarget) =>
sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer)
case AvatarAction.Revive(revivalTargetGuid) case AvatarAction.Revive(revivalTargetGuid)
if resolvedGuid == revivalTargetGuid => if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) =>
ops.revive() ops.revive()
player.Actor ! Player.Revive player.Actor ! Player.Revive
player.History player.History
@ -457,18 +461,20 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
/* uncommon messages (utility, or once in a while) */ /* uncommon messages (utility, or once in a while) */
case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data)
sendResponse(ChangeAmmoMessage(weapon_guid, 1)) sendResponse(ChangeAmmoMessage(weapon_guid, 1))
case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => case AvatarAction.ChangeFireMode(itemGuid, mode)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChangeFireModeMessage(itemGuid, mode)) sendResponse(ChangeFireModeMessage(itemGuid, mode))
case AvatarAction.EnvironmentalDamage(_, _, _) => case AvatarAction.EnvironmentalDamage(_, _, _) =>
//TODO damage marker? //TODO damage marker?
sessionLogic.zoning.CancelZoningProcess() sessionLogic.zoning.CancelZoningProcess()
case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => case AvatarAction.DropCreatedItem(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
/* rare messages */ /* rare messages */
@ -481,10 +487,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) }
)) ))
case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => case AvatarAction.LoadCreatedProjectile(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid))
case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => case AvatarAction.ProjectileExplodes(projectileGuid, projectile) =>
@ -504,10 +512,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
case AvatarAction.ProjectileAutoLockAwareness(mode) => case AvatarAction.ProjectileAutoLockAwareness(mode) =>
sendResponse(GenericActionMessage(mode)) sendResponse(GenericActionMessage(mode))
case AvatarAction.PutDownFDU(target) if isNotSameTarget => case AvatarAction.PutDownFDU(target)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(GenericObjectActionMessage(target, code=53)) sendResponse(GenericObjectActionMessage(target, code=53))
case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => case AvatarAction.StowEquipment(target, slot, item)
if TestFilter(_ => isNotSameTarget) =>
val definition = item.Definition val definition = item.Definition
sendResponse( sendResponse(
ObjectCreateDetailedMessage( ObjectCreateDetailedMessage(
@ -519,7 +529,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
) )
case WeaponDryFire(weaponGuid) case WeaponDryFire(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
continent.GUID(weaponGuid).collect { continent.GUID(weaponGuid).collect {
case tool: Tool if tool.Magazine == 0 => case tool: Tool if tool.Magazine == 0 =>
sendResponse(WeaponDryFireMessage(weaponGuid)) sendResponse(WeaponDryFireMessage(weaponGuid))

View file

@ -66,7 +66,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
isCloaking, isCloaking,
isNotRendered, isNotRendered,
canSeeReallyFar canSeeReallyFar
) if isNotSameTarget => ) if TestFilter(_ => isNotSameTarget) =>
val pstateToSave = pstate.copy(timestamp = 0) val pstateToSave = pstate.copy(timestamp = 0)
val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filterGuid.guid) match { val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filterGuid.guid) match {
case Some(SessionAvatarHandlers.LastUpstream(Some(msg), visible, shooting, time)) => (Some(msg), time, msg.pos, visible, shooting) case Some(SessionAvatarHandlers.LastUpstream(Some(msg), visible, shooting, time)) => (Some(msg), time, msg.pos, visible, shooting)
@ -154,7 +154,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value) case AvatarAction.AvatarImplant(ImplantAction.Add, implant_slot, value)
if value == ImplantType.SecondWind.value => if TestFilter(_ => { value == ImplantType.SecondWind.value }) =>
sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Add, implant_slot, 7)) sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Add, implant_slot, 7))
//second wind does not normally load its icon into the shortcut hotbar //second wind does not normally load its icon into the shortcut hotbar
avatar avatar
@ -166,7 +166,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value) case AvatarAction.AvatarImplant(ImplantAction.Remove, implant_slot, value)
if value == ImplantType.SecondWind.value => if TestFilter(_ => { value == ImplantType.SecondWind.value }) =>
sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Remove, implant_slot, value)) sendResponse(AvatarImplantMessage(resolvedGuid, ImplantAction.Remove, implant_slot, value))
//second wind does not normally unload its icon from the shortcut hotbar //second wind does not normally unload its icon from the shortcut hotbar
val shortcut = { val shortcut = {
@ -185,7 +185,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value)) sendResponse(AvatarImplantMessage(resolvedGuid, action, implant_slot, value))
case AvatarAction.ObjectHeld(slot, _) case AvatarAction.ObjectHeld(slot, _)
if isSameTarget && player.VisibleSlots.contains(slot) => if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) =>
sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true))
//Stop using proximity terminals if player unholsters a weapon //Stop using proximity terminals if player unholsters a weapon
continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect {
@ -196,31 +196,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.ObjectHeld(slot, _) case AvatarAction.ObjectHeld(slot, _)
if isSameTarget && slot > -1 => if TestFilter(_ => { isSameTarget && slot > -1 }) =>
sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true))
case AvatarAction.ObjectHeld(_, _) case AvatarAction.ObjectHeld(_, _)
if isSameTarget => () if TestFilter(_ => isSameTarget) => ()
case AvatarAction.ObjectHeld(_, previousSlot) => case AvatarAction.ObjectHeld(_, previousSlot) =>
sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false))
case ChangeFireState_Start(weaponGuid) case ChangeFireState_Start(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
sendResponse(ChangeFireStateMessage_Start(weaponGuid)) sendResponse(ChangeFireStateMessage_Start(weaponGuid))
val entry = ops.lastSeenStreamMessage(filterGuid.guid) val entry = ops.lastSeenStreamMessage(filterGuid.guid)
ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid))) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid)))
case ChangeFireState_Stop(weaponGuid) case ChangeFireState_Stop(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) =>
sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
val entry = ops.lastSeenStreamMessage(filterGuid.guid) val entry = ops.lastSeenStreamMessage(filterGuid.guid)
ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None))
case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => case AvatarAction.LoadCreatedPlayer(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => case AvatarAction.EquipmentCreatedInHand(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) =>
@ -260,7 +262,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
inventory, inventory,
drop, drop,
delete delete
) if resolvedGuid == target => ) if TestFilter(_ => { resolvedGuid == target }) =>
sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(ArmorChangedMessage(target, exosuit, subtype))
sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor))
//happening to this player //happening to this player
@ -360,7 +362,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
oldInventory, oldInventory,
inventory, inventory,
drops drops
) if resolvedGuid == target => ) if TestFilter(_ => { resolvedGuid == target }) =>
sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(ArmorChangedMessage(target, exosuit, subtype))
sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor))
//happening to this player //happening to this player
@ -451,7 +453,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
/* common messages (maybe once every respawn) */ /* common messages (maybe once every respawn) */
case ReloadTool(itemGuid) case ReloadTool(itemGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
case AvatarAction.Killed(cause, mount) => case AvatarAction.Killed(cause, mount) =>
@ -544,11 +546,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent)
} }
case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => case AvatarAction.ReleasePlayer(tplayer)
if TestFilter(_ => isNotSameTarget) =>
sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer)
case AvatarAction.Revive(revivalTargetGuid) case AvatarAction.Revive(revivalTargetGuid)
if resolvedGuid == revivalTargetGuid => if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) =>
log.info(s"No time for rest, ${player.Name}. Back on your feet!") log.info(s"No time for rest, ${player.Name}. Back on your feet!")
ops.revive() ops.revive()
player.Actor ! Player.Revive player.Actor ! Player.Revive
@ -564,19 +567,20 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
/* uncommon messages (utility, or once in a while) */ /* uncommon messages (utility, or once in a while) */
case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data)
sendResponse(ChangeAmmoMessage(weapon_guid, 1)) sendResponse(ChangeAmmoMessage(weapon_guid, 1))
case AvatarAction.ChangeFireMode(itemGuid, mode) case AvatarAction.ChangeFireMode(itemGuid, mode)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChangeFireModeMessage(itemGuid, mode)) sendResponse(ChangeFireModeMessage(itemGuid, mode))
case AvatarAction.EnvironmentalDamage(_, _, _) => case AvatarAction.EnvironmentalDamage(_, _, _) =>
//TODO damage marker? //TODO damage marker?
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg")
case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => case AvatarAction.DropCreatedItem(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
/* rare messages */ /* rare messages */
@ -589,10 +593,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) }
)) ))
case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => case AvatarAction.LoadCreatedProjectile(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid))
case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => case AvatarAction.ProjectileExplodes(projectileGuid, projectile) =>
@ -612,10 +618,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
case AvatarAction.ProjectileAutoLockAwareness(mode) => case AvatarAction.ProjectileAutoLockAwareness(mode) =>
sendResponse(GenericActionMessage(mode)) sendResponse(GenericActionMessage(mode))
case AvatarAction.PutDownFDU(target) if isNotSameTarget => case AvatarAction.PutDownFDU(target)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(GenericObjectActionMessage(target, code=53)) sendResponse(GenericObjectActionMessage(target, code=53))
case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => case AvatarAction.StowEquipment(target, slot, item)
if TestFilter(_ => isNotSameTarget) =>
val definition = item.Definition val definition = item.Definition
sendResponse( sendResponse(
ObjectCreateDetailedMessage( ObjectCreateDetailedMessage(
@ -627,7 +635,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
) )
case WeaponDryFire(weaponGuid) case WeaponDryFire(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
continent.GUID(weaponGuid).collect { continent.GUID(weaponGuid).collect {
case tool: Tool if tool.Magazine == 0 => case tool: Tool if tool.Magazine == 0 =>
sendResponse(WeaponDryFireMessage(weaponGuid)) sendResponse(WeaponDryFireMessage(weaponGuid))

View file

@ -82,7 +82,8 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
val popVS = pop.count(_.Faction == PlanetSideEmpire.VS) val popVS = pop.count(_.Faction == PlanetSideEmpire.VS)
sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO)) sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
case GalaxyAction.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) => case GalaxyAction.LogStatusChange(name)
if TestFilter(_ => avatar.people.friend.exists(_.name.equals(name))) =>
avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name) avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name)
} }
} }

View file

@ -49,7 +49,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
sendResponse(msg) sendResponse(msg)
} }
case LocalAction.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget => case LocalAction.DeployableMapIcon(behavior, deployInfo)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo)) sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo))
case LocalAction.DeployableUIFor(item) => case LocalAction.DeployableUIFor(item) =>
@ -68,7 +69,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
case LocalAction.Detonate(_, obj) => case LocalAction.Detonate(_, obj) =>
log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly") log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly")
case LocalAction.DoorOpens(_, door) if isNotSameTarget => case LocalAction.DoorOpens(_, door)
if TestFilter(_ => isNotSameTarget) =>
val doorGuid = door.GUID val doorGuid = door.GUID
val pos = player.Position.xy val pos = player.Position.xy
val range = ops.doorLoadRange() val range = ops.doorLoadRange()
@ -86,7 +88,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
case LocalAction.DoorCloses(doorGuid) => //door closes for everyone case LocalAction.DoorCloses(doorGuid) => //door closes for everyone
sendResponse(GenericObjectStateMsg(doorGuid, state=17)) sendResponse(GenericObjectStateMsg(doorGuid, state=17))
case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _) if obj.Destroyed => case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _)
if TestFilter(_ => obj.Destroyed) =>
sendResponse(ObjectDeleteMessage(dguid, unk1=0)) sendResponse(ObjectDeleteMessage(dguid, unk1=0))
case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) => case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) =>
@ -100,21 +103,23 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
) )
case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _) case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _)
if obj.Destroyed || obj.Jammed || obj.Health == 0 => if TestFilter(_ => { obj.Destroyed || obj.Jammed || obj.Health == 0 }) =>
sendResponse(ObjectDeleteMessage(dguid, unk1=0)) sendResponse(ObjectDeleteMessage(dguid, unk1=0))
case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) => case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) =>
obj.Destroyed = true obj.Destroyed = true
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect)
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Active && obj.Destroyed => case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _)
if TestFilter(_ => { obj.Active && obj.Destroyed }) =>
//if active, deactivate //if active, deactivate
obj.Active = false obj.Active = false
ops.deactivateTelpadDeployableMessages(dguid) ops.deactivateTelpadDeployableMessages(dguid)
//standard deployable elimination behavior //standard deployable elimination behavior
sendResponse(ObjectDeleteMessage(dguid, unk1=0)) sendResponse(ObjectDeleteMessage(dguid, unk1=0))
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) if obj.Active => case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _)
if TestFilter(_ => obj.Active) =>
//if active, deactivate //if active, deactivate
obj.Active = false obj.Active = false
ops.deactivateTelpadDeployableMessages(dguid) ops.deactivateTelpadDeployableMessages(dguid)
@ -122,7 +127,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
obj.Destroyed = true obj.Destroyed = true
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2)
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Destroyed => case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _)
if TestFilter(_ => obj.Destroyed) =>
//standard deployable elimination behavior //standard deployable elimination behavior
sendResponse(ObjectDeleteMessage(dguid, unk1=0)) sendResponse(ObjectDeleteMessage(dguid, unk1=0))
@ -131,7 +137,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
obj.Destroyed = true obj.Destroyed = true
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2) ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2)
case LocalAction.EliminateDeployable(obj, dguid, _, _) if obj.Destroyed => case LocalAction.EliminateDeployable(obj, dguid, _, _)
if TestFilter(_ => obj.Destroyed) =>
sendResponse(ObjectDeleteMessage(dguid, unk1=0)) sendResponse(ObjectDeleteMessage(dguid, unk1=0))
case LocalAction.EliminateDeployable(obj, dguid, pos, effect) => case LocalAction.EliminateDeployable(obj, dguid, pos, effect) =>
@ -216,7 +223,8 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
case LocalAction.UpdateForceDomeStatus(buildingGuid, false) => case LocalAction.UpdateForceDomeStatus(buildingGuid, false) =>
sendResponse(GenericObjectActionMessage(buildingGuid, 12)) sendResponse(GenericObjectActionMessage(buildingGuid, 12))
case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if isSameTarget => case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid)
if TestFilter(_ => isSameTarget) =>
continent.GUID(vehicleGuid) continent.GUID(vehicleGuid)
.collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) } .collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) }
.collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) } .collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) }

View file

@ -46,7 +46,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
wheelDirection, wheelDirection,
unk5, unk5,
unk6 unk6
) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => ) if TestFilter(_ => { isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) =>
//player who is also in the vehicle (not driver) //player who is also in the vehicle (not driver)
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
player.Position = pos player.Position = pos
@ -74,30 +74,36 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
wheelDirection, wheelDirection,
unk5, unk5,
unk6 unk6
) if isNotSameTarget => ) if TestFilter(_ => isNotSameTarget) =>
//player who is watching the vehicle from the outside //player who is watching the vehicle from the outside
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => case VehicleAction.ChildObjectState(objectGuid, pitch, yaw)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw))
case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA))
case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => case VehicleAction.DismountVehicle(bailType, wasKickedByDriver)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver)) sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver))
case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => case VehicleAction.MountVehicle(vehicleGuid, seat)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat)) sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat))
case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos)) sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos))
case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => case VehicleAction.EquipmentCreatedInSlot(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => case VehicleAction.InventoryState(obj, parentGuid, start, conData)
if TestFilter(_ => isNotSameTarget) =>
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
val objGuid = obj.GUID val objGuid = obj.GUID
sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) sendResponse(ObjectDeleteMessage(objGuid, unk1=0))
@ -108,7 +114,8 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
conData conData
)) ))
case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if isSameTarget => case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid)
if TestFilter(_ => isSameTarget) =>
//seat number (first field) seems to be correct if passenger is kicked manually by driver //seat number (first field) seems to be correct if passenger is kicked manually by driver
//but always seems to return 4 if user is kicked by mount permissions changing //but always seems to return 4 if user is kicked by mount permissions changing
sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver))
@ -127,15 +134,18 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
//but always seems to return 4 if user is kicked by mount permissions changing //but always seems to return 4 if user is kicked by mount permissions changing
sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver))
case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => case VehicleAction.InventoryState2(objGuid, parentGuid, value)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value))
case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata)
if TestFilter(_ => isNotSameTarget) =>
//this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible) //this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible)
sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) sendResponse(ObjectCreateMessage(vtype, vguid, vdata))
Vehicles.ReloadAccessPermissions(vehicle, player.Name) Vehicles.ReloadAccessPermissions(vehicle, player.Name)
case VehicleAction.Ownership(vehicleGuid) if isSameTarget => case VehicleAction.Ownership(vehicleGuid)
if TestFilter(_ => isSameTarget) =>
//Only the player that owns this vehicle needs the ownership packet //Only the player that owns this vehicle needs the ownership packet
avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid))
sendResponse(PlanetsideAttributeMessage(resolvedGuid, attribute_type=21, vehicleGuid)) sendResponse(PlanetsideAttributeMessage(resolvedGuid, attribute_type=21, vehicleGuid))
@ -143,10 +153,12 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
case VehicleAction.LoseOwnership(_, vehicleGuid) => case VehicleAction.LoseOwnership(_, vehicleGuid) =>
ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted") ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted")
case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission))
case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if isNotSameTarget => case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData)
if TestFilter(_ => isNotSameTarget) =>
//TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly? //TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly?
sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData)) sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData))
@ -163,7 +175,8 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed")) sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed"))
} }
case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => case VehicleAction.UnstowEquipment(itemGuid)
if TestFilter(_ => isNotSameTarget) =>
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
@ -171,7 +184,8 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction) sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction)
sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint()
case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget => case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete)
if TestFilter(_ => isNotSameTarget) =>
sessionLogic.zoning.interstellarFerry = Some(vehicle) sessionLogic.zoning.interstellarFerry = Some(vehicle)
sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete) sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete)
continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}") continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}")
@ -179,7 +193,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating") log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating")
case VehicleAction.KickCargo(vehicle, speed, delay) case VehicleAction.KickCargo(vehicle, speed, delay)
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => if TestFilter(_ => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 }) =>
val strafe = 1 + Vehicles.CargoOrientation(vehicle) val strafe = 1 + Vehicles.CargoOrientation(vehicle)
val reverseSpeed = if (strafe > 1) { 0 } else { speed } val reverseSpeed = if (strafe > 1) { 0 } else { speed }
//strafe or reverse, not both //strafe or reverse, not both
@ -207,11 +221,11 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp)
case VehicleAction.KickCargo(cargo, _, _) case VehicleAction.KickCargo(cargo, _, _)
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => if TestFilter(_ => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) =>
sessionLogic.vehicles.TotalDriverVehicleControl(cargo) sessionLogic.vehicles.TotalDriverVehicleControl(cargo)
case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory) case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory)
if player.avatar.vehicle.contains(target) => if TestFilter(_ => { player.avatar.vehicle.contains(target) }) =>
//TODO when vehicle weapons can be changed without visual glitches, rewrite this //TODO when vehicle weapons can be changed without visual glitches, rewrite this
continent.GUID(target).collect { case vehicle: Vehicle => continent.GUID(target).collect { case vehicle: Vehicle =>
import net.psforever.login.WorldSession.boolToInt import net.psforever.login.WorldSession.boolToInt
@ -235,7 +249,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
} }
case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _)
if sessionLogic.general.accessedContainer.map(_.GUID).contains(target) => if TestFilter(_ => { sessionLogic.general.accessedContainer.map(_.GUID).contains(target) }) =>
//TODO when vehicle weapons can be changed without visual glitches, rewrite this //TODO when vehicle weapons can be changed without visual glitches, rewrite this
continent.GUID(target).collect { case vehicle: Vehicle => continent.GUID(target).collect { case vehicle: Vehicle =>
//external participant: observe changes to equipment //external participant: observe changes to equipment
@ -273,7 +287,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
sendResponse(GenericObjectActionMessage(playerGuid, code=10)) sendResponse(GenericObjectActionMessage(playerGuid, code=10))
case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _)
if player.VisibleSlots.contains(player.DrawnSlot) => if TestFilter(_ => { player.VisibleSlots.contains(player.DrawnSlot) }) =>
player.DrawnSlot = Player.HandsDownSlot player.DrawnSlot = Player.HandsDownSlot
startPlayerSeatedInVehicle(vehicle) startPlayerSeatedInVehicle(vehicle)

View file

@ -61,7 +61,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
isCloaking, isCloaking,
isNotRendered, isNotRendered,
canSeeReallyFar canSeeReallyFar
) if isNotSameTarget => ) if TestFilter(_ => isNotSameTarget) =>
val pstateToSave = pstate.copy(timestamp = 0) val pstateToSave = pstate.copy(timestamp = 0)
val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filterGuid.guid) match { val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(filterGuid.guid) match {
case Some(SessionAvatarHandlers.LastUpstream(Some(msg), visible, shooting, time)) => (Some(msg), time, msg.pos, visible, shooting) case Some(SessionAvatarHandlers.LastUpstream(Some(msg), visible, shooting, time)) => (Some(msg), time, msg.pos, visible, shooting)
@ -149,7 +149,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.ObjectHeld(slot, _) case AvatarAction.ObjectHeld(slot, _)
if isSameTarget && player.VisibleSlots.contains(slot) => if TestFilter(_ => { isSameTarget && player.VisibleSlots.contains(slot) }) =>
sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true))
//Stop using proximity terminals if player unholsters a weapon //Stop using proximity terminals if player unholsters a weapon
continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect {
@ -160,31 +160,33 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
} }
case AvatarAction.ObjectHeld(slot, _) case AvatarAction.ObjectHeld(slot, _)
if isSameTarget && slot > -1 => if TestFilter(_ => { isSameTarget && slot > -1 }) =>
sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true))
case AvatarAction.ObjectHeld(_, _) case AvatarAction.ObjectHeld(_, _)
if isSameTarget => () if TestFilter(_ => isSameTarget) => ()
case AvatarAction.ObjectHeld(_, previousSlot) => case AvatarAction.ObjectHeld(_, previousSlot) =>
sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false))
case ChangeFireState_Start(weaponGuid) case ChangeFireState_Start(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
sendResponse(ChangeFireStateMessage_Start(weaponGuid)) sendResponse(ChangeFireStateMessage_Start(weaponGuid))
val entry = ops.lastSeenStreamMessage(filterGuid.guid) val entry = ops.lastSeenStreamMessage(filterGuid.guid)
ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid))) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid)))
case ChangeFireState_Stop(weaponGuid) case ChangeFireState_Stop(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } }) =>
sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
val entry = ops.lastSeenStreamMessage(filterGuid.guid) val entry = ops.lastSeenStreamMessage(filterGuid.guid)
ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None))
case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => case AvatarAction.LoadCreatedPlayer(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.EquipmentCreatedInHand(pkt) if isNotSameTarget => case AvatarAction.EquipmentCreatedInHand(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.Destroy(victim, killer, weapon, pos) => case AvatarAction.Destroy(victim, killer, weapon, pos) =>
@ -195,7 +197,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk)) sendResponse(ops.destroyDisplayMessage(killer, victim, method, unk))
case AvatarAction.TerminalOrderResult(terminalGuid, action, result) case AvatarAction.TerminalOrderResult(terminalGuid, action, result)
if result && (action == TransactionType.Buy || action == TransactionType.Loadout) => if TestFilter(_ => { result && (action == TransactionType.Buy || action == TransactionType.Loadout) }) =>
sendResponse(ItemTransactionResultMessage(terminalGuid, action, result)) sendResponse(ItemTransactionResultMessage(terminalGuid, action, result))
sessionLogic.terminals.lastTerminalOrderFulfillment = true sessionLogic.terminals.lastTerminalOrderFulfillment = true
AvatarActor.savePlayerData(player) AvatarActor.savePlayerData(player)
@ -217,7 +219,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
inventory, inventory,
drop, drop,
delete delete
) if resolvedGuid == target => ) if TestFilter(_ => { resolvedGuid == target }) =>
sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(ArmorChangedMessage(target, exosuit, subtype))
sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor)) sendResponse(PlanetsideAttributeMessage(target, attribute_type=4, armor))
//happening to this player //happening to this player
@ -295,7 +297,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
oldInventory, oldInventory,
inventory, inventory,
drops drops
) if resolvedGuid == target => ) if TestFilter(_ => { resolvedGuid == target }) =>
sendResponse(ArmorChangedMessage(target, exosuit, subtype)) sendResponse(ArmorChangedMessage(target, exosuit, subtype))
sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor)) sendResponse(PlanetsideAttributeMessage(target, attribute_type = 4, armor))
//happening to this player //happening to this player
@ -351,7 +353,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sessionLogic.general.kitToBeUsed = None sessionLogic.general.kitToBeUsed = None
sendResponse(ChatMsg(ChatMessageType.UNK_225, msg)) sendResponse(ChatMsg(ChatMessageType.UNK_225, msg))
case AvatarAction.UpdateKillsDeathsAssists(_, kda: Kill) if kda.experienceEarned > 0 => case AvatarAction.UpdateKillsDeathsAssists(_, kda: Kill)
if TestFilter(_ => kda.experienceEarned > 0) =>
continent.actor ! ZoneActor.RewardOurSupporters( continent.actor ! ZoneActor.RewardOurSupporters(
PlayerSource(player), PlayerSource(player),
Players.produceContributionTranscriptFromKill(continent, player, kda), Players.produceContributionTranscriptFromKill(continent, player, kda),
@ -386,7 +389,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
/* common messages (maybe once every respawn) */ /* common messages (maybe once every respawn) */
case ReloadTool(itemGuid) case ReloadTool(itemGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible }}) =>
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
case AvatarAction.Killed(_, mount) => case AvatarAction.Killed(_, mount) =>
@ -440,10 +443,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent) sessionLogic.zoning.spawn.HandleReleaseAvatar(player, continent)
} }
case AvatarAction.ReleasePlayer(tplayer) if isNotSameTarget => case AvatarAction.ReleasePlayer(tplayer)
if TestFilter(_ => isNotSameTarget) =>
sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer) sessionLogic.zoning.spawn.DepictPlayerAsCorpse(tplayer)
case AvatarAction.Revive(revivalTargetGuid) if resolvedGuid == revivalTargetGuid => case AvatarAction.Revive(revivalTargetGuid)
if TestFilter(_ => { resolvedGuid == revivalTargetGuid }) =>
log.info(s"No time for rest, ${player.Name}. Back on your feet!") log.info(s"No time for rest, ${player.Name}. Back on your feet!")
sessionLogic.zoning.spawn.reviveTimer.cancel() sessionLogic.zoning.spawn.reviveTimer.cancel()
sessionLogic.zoning.spawn.deadState = DeadState.Alive sessionLogic.zoning.spawn.deadState = DeadState.Alive
@ -458,18 +463,20 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
/* uncommon messages (utility, or once in a while) */ /* uncommon messages (utility, or once in a while) */
case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data)
sendResponse(ChangeAmmoMessage(weapon_guid, 1)) sendResponse(ChangeAmmoMessage(weapon_guid, 1))
case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => case AvatarAction.ChangeFireMode(itemGuid, mode)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChangeFireModeMessage(itemGuid, mode)) sendResponse(ChangeFireModeMessage(itemGuid, mode))
case AvatarAction.EnvironmentalDamage(_, _, _) => case AvatarAction.EnvironmentalDamage(_, _, _) =>
//TODO damage marker? //TODO damage marker?
sessionLogic.zoning.CancelZoningProcess() sessionLogic.zoning.CancelZoningProcess()
case AvatarAction.DropCreatedItem(pkt) if isNotSameTarget => case AvatarAction.DropCreatedItem(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
/* rare messages */ /* rare messages */
@ -482,10 +489,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) } vehicle.flatMap { vinfo => Some(DrowningTarget(vinfo.guid, vinfo.progress, vinfo.state)) }
)) ))
case AvatarAction.LoadCreatedProjectile(pkt) if isNotSameTarget => case AvatarAction.LoadCreatedProjectile(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid) if isNotSameTarget => case AvatarAction.ProjectileState(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid)) sendResponse(ProjectileStateMessage(projectileGuid, shotPos, shotVel, shotOrient, seq, end, targetGuid))
case AvatarAction.ProjectileExplodes(projectileGuid, projectile) => case AvatarAction.ProjectileExplodes(projectileGuid, projectile) =>
@ -505,10 +514,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
case AvatarAction.ProjectileAutoLockAwareness(mode) => case AvatarAction.ProjectileAutoLockAwareness(mode) =>
sendResponse(GenericActionMessage(mode)) sendResponse(GenericActionMessage(mode))
case AvatarAction.PutDownFDU(target) if isNotSameTarget => case AvatarAction.PutDownFDU(target)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(GenericObjectActionMessage(target, code=53)) sendResponse(GenericObjectActionMessage(target, code=53))
case AvatarAction.StowEquipment(target, slot, item) if isNotSameTarget => case AvatarAction.StowEquipment(target, slot, item)
if TestFilter(_ => isNotSameTarget) =>
val definition = item.Definition val definition = item.Definition
sendResponse( sendResponse(
ObjectCreateDetailedMessage( ObjectCreateDetailedMessage(
@ -520,7 +531,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
) )
case WeaponDryFire(weaponGuid) case WeaponDryFire(weaponGuid)
if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => if TestFilter(_ => { isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } }) =>
continent.GUID(weaponGuid).collect { continent.GUID(weaponGuid).collect {
case tool: Tool if tool.Magazine == 0 => case tool: Tool if tool.Magazine == 0 =>
sendResponse(WeaponDryFireMessage(weaponGuid)) sendResponse(WeaponDryFireMessage(weaponGuid))

View file

@ -39,7 +39,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
wheelDirection, wheelDirection,
unk5, unk5,
unk6 unk6
) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) => ) if TestFilter(_ => { isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) =>
//player who is also in the vehicle (not driver) //player who is also in the vehicle (not driver)
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
player.Position = pos player.Position = pos
@ -59,30 +59,36 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
wheelDirection, wheelDirection,
unk5, unk5,
unk6 unk6
) if isNotSameTarget => ) if TestFilter(_ => isNotSameTarget) =>
//player who is watching the vehicle from the outside //player who is watching the vehicle from the outside
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6)) sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
case VehicleAction.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget => case VehicleAction.ChildObjectState(objectGuid, pitch, yaw)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw)) sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw))
case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA) case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA))
case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => case VehicleAction.DismountVehicle(bailType, wasKickedByDriver)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver)) sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver))
case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => case VehicleAction.MountVehicle(vehicleGuid, seat)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat)) sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat))
case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos)) sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos))
case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => case VehicleAction.EquipmentCreatedInSlot(pkt)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(pkt) sendResponse(pkt)
case VehicleAction.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget => case VehicleAction.InventoryState(obj, parentGuid, start, conData)
if TestFilter(_ => isNotSameTarget) =>
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
val objGuid = obj.GUID val objGuid = obj.GUID
sendResponse(ObjectDeleteMessage(objGuid, unk1=0)) sendResponse(ObjectDeleteMessage(objGuid, unk1=0))
@ -93,7 +99,8 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
conData conData
)) ))
case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if isSameTarget => case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid)
if TestFilter(_ => isNotSameTarget) =>
//seat number (first field) seems to be correct if passenger is kicked manually by driver //seat number (first field) seems to be correct if passenger is kicked manually by driver
//but always seems to return 4 if user is kicked by mount permissions changing //but always seems to return 4 if user is kicked by mount permissions changing
sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver))
@ -108,21 +115,25 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
//but always seems to return 4 if user is kicked by mount permissions changing //but always seems to return 4 if user is kicked by mount permissions changing
sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver))
case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => case VehicleAction.InventoryState2(objGuid, parentGuid, value)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value))
case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget => case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata)
if TestFilter(_ => isNotSameTarget) =>
//this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible) //this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible)
sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) sendResponse(ObjectCreateMessage(vtype, vguid, vdata))
Vehicles.ReloadAccessPermissions(vehicle, player.Name) Vehicles.ReloadAccessPermissions(vehicle, player.Name)
case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget => case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission)
if TestFilter(_ => isNotSameTarget) =>
sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission)) sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission))
case VehicleAction.UnloadVehicle(_, vehicleGuid) => case VehicleAction.UnloadVehicle(_, vehicleGuid) =>
sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1)) sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1))
case VehicleAction.UnstowEquipment(itemGuid) if isNotSameTarget => case VehicleAction.UnstowEquipment(itemGuid)
if TestFilter(_ => isNotSameTarget) =>
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly? //TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0)) sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
@ -131,7 +142,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint() sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint()
case VehicleAction.KickCargo(vehicle, speed, delay) case VehicleAction.KickCargo(vehicle, speed, delay)
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 => if TestFilter(_ => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 }) =>
val strafe = 1 + Vehicles.CargoOrientation(vehicle) val strafe = 1 + Vehicles.CargoOrientation(vehicle)
val reverseSpeed = if (strafe > 1) { 0 } else { speed } val reverseSpeed = if (strafe > 1) { 0 } else { speed }
//strafe or reverse, not both //strafe or reverse, not both
@ -159,7 +170,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp) context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp)
case VehicleAction.KickCargo(cargo, _, _) case VehicleAction.KickCargo(cargo, _, _)
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive => if TestFilter(_ => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) =>
sessionLogic.vehicles.TotalDriverVehicleControl(cargo) sessionLogic.vehicles.TotalDriverVehicleControl(cargo)
case VehicleSpawnPad.AttachToRails(vehicle, pad) => case VehicleSpawnPad.AttachToRails(vehicle, pad) =>

View file

@ -2,60 +2,45 @@
package net.psforever.actors.session.support package net.psforever.actors.session.support
import akka.actor.Actor.Receive import akka.actor.Actor.Receive
import net.psforever.objects.{Default, Player} import net.psforever.objects.Default
import net.psforever.services.base.message.EventResponse import net.psforever.services.base.message.EventResponse
import net.psforever.types.PlanetSideGUID import net.psforever.types.PlanetSideGUID
trait HandlerFilter { trait CommonHandlerFunctions {
def resolvedPlayerGuid: PlanetSideGUID _: CommonSessionInterfacingFunctionality =>
def otherPlayerGuid: PlanetSideGUID protected var resolvedGuid: PlanetSideGUID = Default.GUID0
def isNotSameTarget: Boolean protected var filterGuid: PlanetSideGUID = Default.GUID0
def isSameTarget: Boolean protected var isNotSameTarget: Boolean = false
protected var isSameTarget: Boolean = false
def set(filter: HandlerFilter): HandlerFilter = { private var ignoreFilter: Boolean = false
set(filter.resolvedPlayerGuid, filter.otherPlayerGuid, filter.isNotSameTarget, filter.isSameTarget)
def IgnoreFilter: Boolean = ignoreFilter
def IgnoreFilter_=(state: Boolean): Boolean = {
ignoreFilter = state
IgnoreFilter
} }
def set(resolved: PlanetSideGUID, other: PlanetSideGUID, notSame: Boolean, same: Boolean): HandlerFilter
}
class HandlerFilterRules extends HandlerFilter {
var resolvedPlayerGuid: PlanetSideGUID = Default.GUID0
var otherPlayerGuid: PlanetSideGUID = Default.GUID0
var isNotSameTarget: Boolean = false
var isSameTarget: Boolean = false
def set(resolved: PlanetSideGUID, other: PlanetSideGUID, notSame: Boolean, same: Boolean): HandlerFilter = {
resolvedPlayerGuid = resolved
otherPlayerGuid = other
isNotSameTarget = notSame
isSameTarget = same
this
}
}
object HandlerFilter {
def set(filter: HandlerFilter, guid: PlanetSideGUID, player: Player): HandlerFilter = {
if (player != null && player.HasGUID) {
val pguid = player.GUID
filter.set(pguid, guid, pguid != guid, pguid == guid)
} else {
filter.set(Default.GUID0, guid, notSame = true, same = false)
}
filter
}
final val NeverAllow: HandlerFilter = new HandlerFilterRules().set(PlanetSideGUID(-1), PlanetSideGUID(-2), notSame = false, same = false)
}
trait CommonHandlerFunctionsBase {
/** /**
* na * na
* @param toChannel na * @param toChannel na
* @param guid na * @param guid na
* @param reply na * @param reply na
*/ */
def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean = {
filterGuid = guid
if (player != null && player.HasGUID) {
resolvedGuid = player.GUID
isNotSameTarget = resolvedGuid != filterGuid
isSameTarget = resolvedGuid == filterGuid
} else {
resolvedGuid = Default.GUID0
isNotSameTarget = false
isSameTarget = false
}
tryToHandle(reply)
}
def receive: Receive def receive: Receive
@ -66,28 +51,8 @@ trait CommonHandlerFunctionsBase {
receive.applyOrElse(x, (_: Any) => { passed = false }) receive.applyOrElse(x, (_: Any) => { passed = false })
passed passed
} }
}
trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { def TestFilter(filter: Unit => Boolean): Boolean = {
_: CommonSessionInterfacingFunctionality => ignoreFilter || filter()
def resolvedGuid: PlanetSideGUID = sessionLogic.handlerFilter.resolvedPlayerGuid
def filterGuid: PlanetSideGUID = sessionLogic.handlerFilter.otherPlayerGuid
def isNotSameTarget: Boolean = sessionLogic.handlerFilter.isNotSameTarget
def isSameTarget: Boolean = sessionLogic.handlerFilter.isSameTarget
/**
* na
* @param toChannel na
* @param guid na
* @param reply na
*/
def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean = {
HandlerFilter.set(sessionLogic.handlerFilter, guid, player)
tryToHandle(reply)
} }
def receive: Receive
} }

View file

@ -12,48 +12,48 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac
def receive: Receive = { def receive: Receive = {
case PlanetsideAttribute(target_guid, attributeType, attributeValue) case PlanetsideAttribute(target_guid, attributeType, attributeValue)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue)) sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue))
case GenericObjectAction(objectGuid, actionCode) case GenericObjectAction(objectGuid, actionCode)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(GenericObjectActionMessage(objectGuid, actionCode)) sendResponse(GenericObjectActionMessage(objectGuid, actionCode))
case ObjectDelete(itemGuid, unk) case ObjectDelete(itemGuid, unk)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(ObjectDeleteMessage(itemGuid, unk)) sendResponse(ObjectDeleteMessage(itemGuid, unk))
case ChangeFireState_Start(weaponGuid) case ChangeFireState_Start(weaponGuid)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChangeFireStateMessage_Start(weaponGuid)) sendResponse(ChangeFireStateMessage_Start(weaponGuid))
case ChangeFireState_Stop(weaponGuid) case ChangeFireState_Stop(weaponGuid)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
case ReloadTool(itemGuid) case ReloadTool(itemGuid)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sessionLogic.avatarResponse.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sessionLogic.avatarResponse.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data)
sendResponse(ChangeAmmoMessage(weapon_guid, 1)) sendResponse(ChangeAmmoMessage(weapon_guid, 1))
case WeaponDryFire(weaponGuid) case WeaponDryFire(weaponGuid)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
continent.GUID(weaponGuid).collect { continent.GUID(weaponGuid).collect {
case tool: Tool if tool.Magazine == 0 => case tool: Tool if tool.Magazine == 0 =>
sendResponse(WeaponDryFireMessage(weaponGuid)) sendResponse(WeaponDryFireMessage(weaponGuid))
} }
case HintsAtAttacker(sourceGuid) case HintsAtAttacker(sourceGuid)
if player.isAlive => if TestFilter(_ => { player.isAlive }) =>
sendResponse(HitHint(sourceGuid, filterGuid)) sendResponse(HitHint(sourceGuid, filterGuid))
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg")
case SetEmpire(objectGuid, faction) case SetEmpire(objectGuid, faction)
if isNotSameTarget => if TestFilter(_ => isNotSameTarget) =>
sendResponse(SetEmpireMessage(objectGuid, faction)) sendResponse(SetEmpireMessage(objectGuid, faction))
case ConcealPlayer(_) => case ConcealPlayer(_) =>

View file

@ -119,7 +119,6 @@ class SessionData(
def squad: SessionSquadHandlers = squadResponseOpt.orNull def squad: SessionSquadHandlers = squadResponseOpt.orNull
def zoning: ZoningOperations = zoningOpt.orNull def zoning: ZoningOperations = zoningOpt.orNull
def chat: ChatOperations = chatOpt.orNull def chat: ChatOperations = chatOpt.orNull
var handlerFilter: HandlerFilter = HandlerFilter.NeverAllow
ServiceManager.serviceManager ! Lookup("accountIntermediary") ServiceManager.serviceManager ! Lookup("accountIntermediary")
ServiceManager.serviceManager ! Lookup("accountPersistence") ServiceManager.serviceManager ! Lookup("accountPersistence")