From 1e34e8239c6bd8066bd924ad9f8ffff9c1356923 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Sun, 5 Apr 2026 14:13:13 -0400 Subject: [PATCH] wrong filters used to retrieve other player data; re-use the same filter rather than create a new one --- .../actors/session/SessionActor.scala | 79 +++++++++-------- .../session/csr/AvatarHandlerLogic.scala | 40 +++++---- .../session/normal/AvatarHandlerLogic.scala | 43 +++++----- .../session/normal/LocalHandlerLogic.scala | 6 +- .../session/normal/VehicleHandlerLogic.scala | 19 ++--- .../spectator/AvatarHandlerLogic.scala | 40 +++++---- .../spectator/VehicleHandlerLogic.scala | 15 ++-- .../support/CommonHandlerFunctions.scala | 85 +++++++++---------- .../session/support/CommonHandlerLogic.scala | 6 +- .../actors/session/support/SessionData.scala | 1 + ...nericEventServiceWithCacheAndSupport.scala | 6 +- 11 files changed, 168 insertions(+), 172 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 7150759f1..fed366a6f 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -3,7 +3,7 @@ package net.psforever.actors.session import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware, typed} import net.psforever.actors.session.normal.NormalMode -import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerLogic, HandlerFilter, ZoningOperations} +import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerFunctionsBase, CommonHandlerLogic, HandlerFilter, ZoningOperations} import net.psforever.objects.TurretDeployable import net.psforever.objects.serverobject.CommonMessages import net.psforever.objects.serverobject.containable.Containable @@ -123,7 +123,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con buffer.addOne(msg) case _ if data.whenAllEventBusesLoaded() => context.become(inTheGame) - logic = mode.setup(data) + changeModeSetup(mode) buffer.foreach { self.tell(_, self) } //we forget the original sender, shouldn't be doing callbacks at this point buffer.clear() case _ => () @@ -164,18 +164,22 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con if (mode != newMode) { logic.switchFrom(data.session) mode = newMode - logic = newMode.setup(data) - listOfHandlers = List( - logic.avatarResponse, - logic.local, - logic.vehicleResponse, - logic.galaxy, - commonHandlerLogic - ) + changeModeSetup(newMode) } logic.switchTo(data.session) } + private def changeModeSetup(newMode: PlayerMode): Unit = { + logic = newMode.setup(data) + listOfHandlers = List( + logic.avatarResponse, + logic.local, + logic.vehicleResponse, + logic.galaxy, + commonHandlerLogic + ) + } + private def parse(sender: ActorRef): Receive = { /* really common messages (very frequently, every life) */ case packet: PlanetSideGamePacket => @@ -372,39 +376,46 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con } private def handleGenericResponseEnvelope(envelope: GenericResponseEnvelope): Unit = { - val GenericResponseEnvelope(_, guid, reply) = envelope //try use the stamp to match the specific handler - val primaryHandler = envelope.stamp match { + envelope.stamp match { case Undelivered => + val GenericResponseEnvelope(_, _, reply) = envelope log.error(s"received a message's response that was not processed by an event system - $reply") - CommonHandlerFunctions.HandleAnything case AvatarStamp => - logic.avatarResponse + handleEnvelopeWithResponseHandler(logic.avatarResponse, envelope) case LocalStamp => - logic.local + handleEnvelopeWithResponseHandler(logic.local, envelope) case VehicleStamp => - logic.vehicleResponse + handleEnvelopeWithResponseHandler(logic.vehicleResponse, envelope) case GalaxyStamp => - logic.galaxy + handleEnvelopeWithResponseHandler(logic.galaxy, envelope) case unknownStamp => - log.error(s"received a message's response from an unknown event system - stamp: $unknownStamp") - CommonHandlerFunctions.HandleNothing + log.error(s"received a message from an unknown event system - reply: $envelope, stamp: $unknownStamp") } - //try the handler on the input message - val filter = HandlerFilter(guid, data.player) - lazy val alwaysAllowFilter = HandlerFilter.Allow(guid) - if (primaryHandler.handleWith(filter).isDefinedAt(reply)) { - primaryHandler.receive.apply(reply) - } else if (!primaryHandler.handleWith(alwaysAllowFilter).isDefinedAt(reply)) { - //check a list of all handlers for any potentially valid case - val potentiallyValidHandlers = listOfHandlers.filter(_.handleWith(alwaysAllowFilter).isDefinedAt(reply)) - if (potentiallyValidHandlers.nonEmpty) { - potentiallyValidHandlers - .find(_.handleWith(filter).isDefinedAt(reply)) - .foreach(_.receive.apply(reply)) - //arrive here without processing input, the guard for a handler blocked a case; not gonna fault - } else { - log.error(s"received completely unhandled response message - $envelope") + } + + private def handleEnvelopeWithResponseHandler( + responseHandler: CommonHandlerFunctionsBase, + envelope: GenericResponseEnvelope + ): Unit = { + val GenericResponseEnvelope(_, guid, reply) = envelope + //try the expected handler with the input response + val filter = HandlerFilter.set(data.handlerFilter, guid, data.player) + if (responseHandler.isDefinedAt(reply)) { + responseHandler.receive.apply(reply) + } else { + //find any handler that might receive the response (ignore guard booleans during search) + data.handlerFilter.set(guid, guid, notSame = true, same = true) + if (!responseHandler.isDefinedAt(reply)) { + val potentiallyValidHandlers = listOfHandlers.filter(_.isDefinedAt(reply)) + if (potentiallyValidHandlers.nonEmpty) { + data.handlerFilter.set(filter) + potentiallyValidHandlers + .find(_.isDefinedAt(reply)) + .foreach(_.receive.apply(reply)) + } else { + log.error(s"received completely unhandled response message - $envelope for ${envelope.stamp}") + } } } } diff --git a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala index 4ad3e6dc7..8ab40b969 100644 --- a/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/AvatarHandlerLogic.scala @@ -82,7 +82,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A canSeeReallyFar ) if isNotSameTarget => val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(resolvedGuid.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 _ => (None, 0L, Vector3.Zero, false, None) } @@ -125,7 +125,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //must draw sendResponse( PlayerStateMessage( - resolvedGuid, + filterGuid, pos, vel, yaw, @@ -138,10 +138,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) } } else { //conditions where the target is not currently visible @@ -150,7 +150,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat sendResponse( PlayerStateMessage( - resolvedGuid, + filterGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -160,10 +160,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) } else { //skip drawing altogether - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } @@ -200,7 +200,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(slot, _) if isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) + sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { case term: Terminal with ProximityUnit => sessionLogic.terminals.StopUsingProximityUnit(term) @@ -211,25 +211,25 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(slot, _) if isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) + sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) if isSameTarget => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(resolvedGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = Some(weaponGuid))) + val entry = ops.lastSeenStreamMessage(filterGuid.guid) + ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid))) case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = None)) + val entry = ops.lastSeenStreamMessage(filterGuid.guid) + ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) @@ -411,7 +411,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(_, mount) => @@ -470,7 +470,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* uncommon messages (utility, or once in a while) */ case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget => ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) @@ -532,11 +532,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => - // check that the magazine is still empty before sending WeaponDryFireMessage - // if it has been reloaded since then, other clients will not see it firing sendResponse(WeaponDryFireMessage(weaponGuid)) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala index 66ebd97fe..1a22a3bd2 100644 --- a/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/AvatarHandlerLogic.scala @@ -68,7 +68,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A canSeeReallyFar ) if isNotSameTarget => val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(resolvedGuid.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 _ => (None, 0L, Vector3.Zero, false, None) } @@ -111,7 +111,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //must draw sendResponse( PlayerStateMessage( - resolvedGuid, + filterGuid, pos, vel, yaw, @@ -124,10 +124,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) } } else { //conditions where the target is not currently visible @@ -136,7 +136,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat sendResponse( PlayerStateMessage( - resolvedGuid, + filterGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -146,10 +146,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) } else { //skip drawing altogether - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } @@ -186,7 +186,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(slot, _) if isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) + sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { case term: Terminal with ProximityUnit => sessionLogic.terminals.StopUsingProximityUnit(term) @@ -197,25 +197,25 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(slot, _) if isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) + sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) if isSameTarget => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(resolvedGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = Some(weaponGuid))) + val entry = ops.lastSeenStreamMessage(filterGuid.guid) + ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid))) case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = None)) + val entry = ops.lastSeenStreamMessage(filterGuid.guid) + ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) @@ -224,7 +224,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A sendResponse(pkt) case AvatarAction.PlanetsideStringAttribute(attributeType, attributeValue) => - sendResponse(PlanetsideStringAttributeMessage(resolvedGuid, attributeType, attributeValue)) + sendResponse(PlanetsideStringAttributeMessage(filterGuid, attributeType, attributeValue)) case AvatarAction.Destroy(victim, killer, weapon, pos) => // guid = victim // killer = killer @@ -564,11 +564,12 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* uncommon messages (utility, or once in a while) */ case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget => ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) - case AvatarAction.ChangeFireMode(itemGuid, mode) if isNotSameTarget => + case AvatarAction.ChangeFireMode(itemGuid, mode) + if isNotSameTarget => sendResponse(ChangeFireModeMessage(itemGuid, mode)) case AvatarAction.EnvironmentalDamage(_, _, _) => @@ -626,11 +627,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => - // check that the magazine is still empty before sending WeaponDryFireMessage - // if it has been reloaded since then, other clients will not see it firing sendResponse(WeaponDryFireMessage(weaponGuid)) } } diff --git a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala index 1c108d951..11a6741ea 100644 --- a/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/LocalHandlerLogic.scala @@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.vehicles.MountableWeapons import net.psforever.objects.{BoomerDeployable, ExplosiveDeployable, TelepadDeployable, Tool, TurretDeployable} import net.psforever.packet.game.{ChatMsg, DeployableObjectsInfoMessage, GenericActionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HackMessage, HackState, HackState1, InventoryStateMessage, ObjectAttachMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, OrbitalShuttleTimeMsg, PadAndShuttlePair, PlanetsideAttributeMessage, ProximityTerminalUseMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage} -import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse} +import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.{InterstellarClusterService, Service} import net.psforever.services.local.LocalAction import net.psforever.types.{ChatMessageType, SpawnGroup} @@ -139,7 +139,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect) case LocalAction.HackClear(targetGuid, unk1, unk2) => - sendResponse(HackMessage(HackState1.Unk0, targetGuid, resolvedGuid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) + sendResponse(HackMessage(HackState1.Unk0, targetGuid, filterGuid, progress=0, unk1.toFloat, HackState.HackCleared, unk2)) case LocalAction.HackObject(targetGuid, unk1, unk2) => sessionLogic.general.hackObject(targetGuid, unk1, unk2) @@ -216,7 +216,7 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act case LocalAction.UpdateForceDomeStatus(buildingGuid, false) => sendResponse(GenericObjectActionMessage(buildingGuid, 12)) - case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if isSameTarget /*resolvedPlayerGuid == guid*/ => + case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if isSameTarget => continent.GUID(vehicleGuid) .collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) } .collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) } diff --git a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala index c392bda74..55c46f01a 100644 --- a/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/VehicleHandlerLogic.scala @@ -6,17 +6,16 @@ import akka.actor.{ActorContext, ActorRef, typed} import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.support.{SessionData, SessionVehicleHandlers, VehicleHandlerFunctions} import net.psforever.objects.avatar.SpecialCarry -import net.psforever.objects.{GlobalDefinitions, Player, Tool, Vehicle, Vehicles} +import net.psforever.objects.{GlobalDefinitions, Player, Vehicle, Vehicles} import net.psforever.objects.equipment.{Equipment, JammableMountedWeapons, JammableUnit} import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects.serverobject.interior.Sidedness.OutsideOf import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, HitHint, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ReloadMessage, ServerVehicleOverrideMsg, VehicleStateMessage, WeaponDryFireMessage} +import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ServerVehicleOverrideMsg, VehicleStateMessage} import net.psforever.services.Service import net.psforever.services.base.envelope.GenericResponseEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.local.support.CaptureFlagManager import net.psforever.services.vehicle.{VehicleAction, VehicleStamp} import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3} @@ -87,13 +86,13 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => - sendResponse(DismountVehicleMsg(resolvedGuid, bailType, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver)) case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => - sendResponse(ObjectAttachMessage(vehicleGuid, resolvedGuid, seat)) + sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat)) case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => - sendResponse(DeployRequestMessage(resolvedGuid, objectGuid, state, unk1, unk2, pos)) + sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos)) case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) @@ -109,10 +108,10 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: conData )) - case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if isSameTarget /*resolvedPlayerGuid == guid*/ => + case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if isSameTarget => //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 - sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) val typeOfRide = continent.GUID(vehicleGuid) match { case Some(obj: Vehicle) => sessionLogic.general.unaccessContainer(obj) @@ -126,7 +125,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.KickPassenger(_, wasKickedByDriver, _) => //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 - sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) @@ -136,7 +135,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(ObjectCreateMessage(vtype, vguid, vdata)) Vehicles.ReloadAccessPermissions(vehicle, player.Name) - case VehicleAction.Ownership(vehicleGuid) if isSameTarget /*resolvedPlayerGuid == guid*/ => + case VehicleAction.Ownership(vehicleGuid) if isSameTarget => //Only the player that owns this vehicle needs the ownership packet avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid)) sendResponse(PlanetsideAttributeMessage(resolvedGuid, attribute_type=21, vehicleGuid)) diff --git a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala index 1e4f0b3f6..f5db7b804 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/AvatarHandlerLogic.scala @@ -63,7 +63,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A canSeeReallyFar ) if isNotSameTarget => val pstateToSave = pstate.copy(timestamp = 0) - val (lastMsg, lastTime, lastPosition, wasVisible, wasShooting) = ops.lastSeenStreamMessage.get(resolvedGuid.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 _ => (None, 0L, Vector3.Zero, false, None) } @@ -106,7 +106,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A //must draw sendResponse( PlayerStateMessage( - resolvedGuid, + filterGuid, pos, vel, yaw, @@ -119,10 +119,10 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A isCloaking ) ) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, now)) } else { //is visible, but skip reinforcement - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=true, wasShooting, lastTime)) } } else { //conditions where the target is not currently visible @@ -131,7 +131,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A val lat = (1 + ops.hidingPlayerRandomizer.nextInt(continent.map.scale.height.toInt)).toFloat sendResponse( PlayerStateMessage( - resolvedGuid, + filterGuid, Vector3(1f, lat, 1f), vel=None, facingYaw=0f, @@ -141,16 +141,16 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A is_cloaked = isCloaking ) ) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, now)) } else { //skip drawing altogether - ops.lastSeenStreamMessage.put(resolvedGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) + ops.lastSeenStreamMessage.put(filterGuid.guid, SessionAvatarHandlers.LastUpstream(Some(pstateToSave), visible=false, wasShooting, lastTime)) } } case AvatarAction.ObjectHeld(slot, _) if isSameTarget && player.VisibleSlots.contains(slot) => - sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) + sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) //Stop using proximity terminals if player unholsters a weapon continent.GUID(sessionLogic.terminals.usingMedicalTerminal).collect { case term: Terminal with ProximityUnit => sessionLogic.terminals.StopUsingProximityUnit(term) @@ -161,25 +161,25 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A case AvatarAction.ObjectHeld(slot, _) if isSameTarget && slot > -1 => - sendResponse(ObjectHeldMessage(resolvedGuid, slot, unk1=true)) + sendResponse(ObjectHeldMessage(filterGuid, slot, unk1=true)) case AvatarAction.ObjectHeld(_, _) if isSameTarget => () case AvatarAction.ObjectHeld(_, previousSlot) => - sendResponse(ObjectHeldMessage(resolvedGuid, previousSlot, unk1=false)) + sendResponse(ObjectHeldMessage(filterGuid, previousSlot, unk1=false)) case ChangeFireState_Start(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => sendResponse(ChangeFireStateMessage_Start(weaponGuid)) - val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = Some(weaponGuid))) + val entry = ops.lastSeenStreamMessage(filterGuid.guid) + ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = Some(weaponGuid))) case ChangeFireState_Stop(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { msg => msg.visible || msg.shooting.nonEmpty } => sendResponse(ChangeFireStateMessage_Stop(weaponGuid)) - val entry = ops.lastSeenStreamMessage(resolvedGuid.guid) - ops.lastSeenStreamMessage.put(resolvedGuid.guid, entry.copy(shooting = None)) + val entry = ops.lastSeenStreamMessage(filterGuid.guid) + ops.lastSeenStreamMessage.put(filterGuid.guid, entry.copy(shooting = None)) case AvatarAction.LoadCreatedPlayer(pkt) if isNotSameTarget => sendResponse(pkt) @@ -386,7 +386,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* common messages (maybe once every respawn) */ case ReloadTool(itemGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0)) case AvatarAction.Killed(_, mount) => @@ -458,7 +458,7 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A /* uncommon messages (utility, or once in a while) */ case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget => ops.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data) sendResponse(ChangeAmmoMessage(weapon_guid, 1)) @@ -520,11 +520,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A ) case WeaponDryFire(weaponGuid) - if isNotSameTarget && ops.lastSeenStreamMessage.get(resolvedGuid.guid).exists { _.visible } => + if isNotSameTarget && ops.lastSeenStreamMessage.get(filterGuid.guid).exists { _.visible } => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => - // check that the magazine is still empty before sending WeaponDryFireMessage - // if it has been reloaded since then, other clients will not see it firing sendResponse(WeaponDryFireMessage(weaponGuid)) } } diff --git a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala index b1c1e4fbb..21ca3d946 100644 --- a/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/spectator/VehicleHandlerLogic.scala @@ -4,13 +4,12 @@ package net.psforever.actors.session.spectator import akka.actor.Actor.Receive import akka.actor.ActorContext import net.psforever.actors.session.support.{SessionData, SessionVehicleHandlers, VehicleHandlerFunctions} -import net.psforever.objects.{Tool, Vehicle, Vehicles} +import net.psforever.objects.{Vehicle, Vehicles} import net.psforever.objects.equipment.Equipment import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent -import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ReloadMessage, ServerVehicleOverrideMsg, VehicleStateMessage, WeaponDryFireMessage} +import net.psforever.packet.game.{ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ServerVehicleOverrideMsg, VehicleStateMessage} import net.psforever.services.base.envelope.GenericResponseEnvelope -import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, GenericObjectAction, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, WeaponDryFire} import net.psforever.services.vehicle.{VehicleAction, VehicleStamp} import net.psforever.types.{BailType, PlanetSideGUID, Vector3} @@ -72,13 +71,13 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)) case VehicleAction.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget => - sendResponse(DismountVehicleMsg(resolvedGuid, bailType, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(filterGuid, bailType, wasKickedByDriver)) case VehicleAction.MountVehicle(vehicleGuid, seat) if isNotSameTarget => - sendResponse(ObjectAttachMessage(vehicleGuid, resolvedGuid, seat)) + sendResponse(ObjectAttachMessage(vehicleGuid, filterGuid, seat)) case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget => - sendResponse(DeployRequestMessage(resolvedGuid, objectGuid, state, unk1, unk2, pos)) + sendResponse(DeployRequestMessage(filterGuid, objectGuid, state, unk1, unk2, pos)) case VehicleAction.EquipmentCreatedInSlot(pkt) if isNotSameTarget => sendResponse(pkt) @@ -97,7 +96,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid) if isSameTarget => //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 - sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) continent.GUID(vehicleGuid) match { case Some(obj: Vehicle) => sessionLogic.general.unaccessContainer(obj) @@ -107,7 +106,7 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context: case VehicleAction.KickPassenger(_, wasKickedByDriver, _) => //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 - sendResponse(DismountVehicleMsg(resolvedGuid, BailType.Kicked, wasKickedByDriver)) + sendResponse(DismountVehicleMsg(filterGuid, BailType.Kicked, wasKickedByDriver)) case VehicleAction.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget => sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value)) diff --git a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala index 5e2020e31..6669b3239 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerFunctions.scala @@ -9,38 +9,45 @@ import net.psforever.types.PlanetSideGUID trait HandlerFilter { def resolvedPlayerGuid: PlanetSideGUID + def otherPlayerGuid: PlanetSideGUID def isNotSameTarget: Boolean def isSameTarget: Boolean + + def set(resolved: PlanetSideGUID, other: PlanetSideGUID, notSame: Boolean, same: Boolean): HandlerFilter + def set(filter: HandlerFilter): HandlerFilter } -case class HandlerFilterRules( - resolvedPlayerGuid: PlanetSideGUID, - isNotSameTarget: Boolean, - isSameTarget: Boolean - ) extends HandlerFilter +class HandlerFilterRules extends HandlerFilter { + var resolvedPlayerGuid: PlanetSideGUID = Service.defaultPlayerGUID + var otherPlayerGuid: PlanetSideGUID = Service.defaultPlayerGUID + 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 + } + + def set(filter: HandlerFilter): HandlerFilter = { + set(filter.resolvedPlayerGuid, filter.otherPlayerGuid, filter.isNotSameTarget, filter.isSameTarget) + } +} object HandlerFilter { - def apply(guid: PlanetSideGUID, isNotSameTarget: Boolean): HandlerFilter = { - HandlerFilterRules(guid, isNotSameTarget, !isNotSameTarget) - } - - def apply(guid1: PlanetSideGUID, guid2: PlanetSideGUID): HandlerFilter = { - val resolvedPlayerGuid: PlanetSideGUID = guid2 - val isNotSameTarget: Boolean = resolvedPlayerGuid != guid1 - this(guid2, isNotSameTarget) - } - - def apply(guid: PlanetSideGUID, player: Player): HandlerFilter = { - this(guid, if (player != null && player.HasGUID) { - player.GUID + 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 { - Service.defaultPlayerGUID - }) + filter.set(Service.defaultPlayerGUID, guid, notSame = true, same = false) + } + filter } - final val NeverAllow: HandlerFilter = HandlerFilterRules(PlanetSideGUID(-1), isNotSameTarget = false, isSameTarget = false) - - final def Allow(guid: PlanetSideGUID): HandlerFilter = HandlerFilterRules(guid, isNotSameTarget = true, isSameTarget = true) + final val NeverAllow: HandlerFilter = new HandlerFilterRules().set(PlanetSideGUID(-1), PlanetSideGUID(-2), notSame = false, same = false) } trait CommonHandlerFunctionsBase { @@ -57,17 +64,19 @@ trait CommonHandlerFunctionsBase { def handleWith(filter: HandlerFilter): Receive def receive: Receive + + def isDefinedAt(x: Any): Boolean = receive.isDefinedAt(x) } trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { _: CommonSessionInterfacingFunctionality => - private var filter: HandlerFilter = HandlerFilter.NeverAllow + def resolvedGuid: PlanetSideGUID = sessionLogic.handlerFilter.resolvedPlayerGuid - def resolvedGuid: PlanetSideGUID = filter.resolvedPlayerGuid + def filterGuid: PlanetSideGUID = sessionLogic.handlerFilter.otherPlayerGuid - def isNotSameTarget: Boolean = filter.isNotSameTarget + def isNotSameTarget: Boolean = sessionLogic.handlerFilter.isNotSameTarget - def isSameTarget: Boolean = filter.isSameTarget + def isSameTarget: Boolean = sessionLogic.handlerFilter.isSameTarget /** * na @@ -76,35 +85,19 @@ trait CommonHandlerFunctions extends CommonHandlerFunctionsBase { * @param reply na */ def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { - filter = HandlerFilter(guid, player) + HandlerFilter.set(sessionLogic.handlerFilter, guid, player) receive.apply(reply) } def handleWith(guid: PlanetSideGUID): Receive = { - filter = HandlerFilter(guid, player) + HandlerFilter.set(sessionLogic.handlerFilter, guid, player) receive } def handleWith(giveFilter: HandlerFilter): Receive = { - filter = giveFilter + sessionLogic.handlerFilter = giveFilter receive } def receive: Receive } - -object CommonHandlerFunctions { - val HandleNothing: CommonHandlerFunctionsBase = new CommonHandlerFunctionsBase { - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = { } - def handleWith(guid: PlanetSideGUID): Receive = receive - def handleWith(filter: HandlerFilter): Receive = receive - def receive: Receive = { case _: CommonHandlerFunctions => () } - } - - val HandleAnything: CommonHandlerFunctionsBase = new CommonHandlerFunctionsBase { - def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Unit = receive.apply(reply) - def handleWith(guid: PlanetSideGUID): Receive = receive - def handleWith(filter: HandlerFilter): Receive = receive - def receive: Receive = { case _ => () } - } -} diff --git a/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala b/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala index c0e5772b9..9eff6b114 100644 --- a/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala +++ b/src/main/scala/net/psforever/actors/session/support/CommonHandlerLogic.scala @@ -44,14 +44,12 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac if isNotSameTarget => continent.GUID(weaponGuid).collect { case tool: Tool if tool.Magazine == 0 => - // check that the magazine is still empty before sending WeaponDryFireMessage - // if it has been reloaded since then, other clients will not see it firing sendResponse(WeaponDryFireMessage(weaponGuid)) } case HintsAtAttacker(sourceGuid) if player.isAlive => - sendResponse(HitHint(sourceGuid, resolvedGuid)) + sendResponse(HitHint(sourceGuid, filterGuid)) sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg") case SetEmpire(objectGuid, faction) @@ -59,7 +57,7 @@ class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: Ac sendResponse(SetEmpireMessage(objectGuid, faction)) case ConcealPlayer(_) => - sendResponse(GenericObjectActionMessage(resolvedGuid, code=9)) + sendResponse(GenericObjectActionMessage(filterGuid, code=9)) case SendResponse(msgs) => msgs.foreach(sendResponse) diff --git a/src/main/scala/net/psforever/actors/session/support/SessionData.scala b/src/main/scala/net/psforever/actors/session/support/SessionData.scala index 0d43257a8..2f193d205 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -119,6 +119,7 @@ class SessionData( def squad: SessionSquadHandlers = squadResponseOpt.orNull def zoning: ZoningOperations = zoningOpt.orNull def chat: ChatOperations = chatOpt.orNull + var handlerFilter: HandlerFilter = HandlerFilter.NeverAllow ServiceManager.serviceManager ! Lookup("accountIntermediary") ServiceManager.serviceManager ! Lookup("accountPersistence") diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index ee5a283ac..3f926e1ff 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -145,11 +145,11 @@ class GenericEventServiceWithCacheAndSupport * flush the cache messages to the normal event system bus. */ private def tryFlushCache(): Boolean = { - val willFLush = hasCachedMessages && nextTimeToFlushCache < System.currentTimeMillis() - if (willFLush) { + val willFlush = hasCachedMessages && nextTimeToFlushCache < System.currentTimeMillis() + if (willFlush) { flushCache() } - willFLush + willFlush } /**